找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55114|回复: 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
    * t8 g2 i1 C* }

  2. $ _4 z+ _- D) k9 b, j% Z
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    $ U- J- {/ ?; L- b- L
  4. 4 B5 s. _6 \! d4 E% L5 @
  5. November 4th, 2005, Rev. 1.0
    9 {4 X& b" p- T) o  G
  6. & F9 i. c! E( |9 o# g1 |
  7. ABOUT THE SOFTWARE8 c+ w+ I$ e1 K( J- M
  8. This application note provides software driver examples for SST25VF080B,& v, {& [6 y6 i; f) r9 o( h
  9. Serial Flash. Extensive comments are included in each routine to describe / G/ i, y  {8 g5 B
  10. the function of each routine.  The interface coding uses polling method / j+ j, }; }$ y, e; g9 m' |& e
  11. rather than the SPI protocol to interface with these serial devices.  The
    7 M- E5 A6 `, |; ~- ~  e
  12. functions are differentiated below in terms of the communication protocols" {, L7 m2 y4 ]3 {% [
  13. (uses Mode 0) and specific device operation instructions. This code has been
    / r: d3 T! o6 m9 H/ u
  14. designed to compile using the Keil compiler.
    4 }+ F# D+ n- y0 l) K
  15. . ]6 J' m5 p4 U9 n* b/ H' o
  16. ! l! x- M/ l% o; B( q& I
  17. ABOUT THE SST25VF080B
    . W3 P5 }, T' v4 E

  18. 0 _' C# u! P; ?7 g; I7 |
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    : k! s; g( N" D- J+ F; L
  20. conjunction with this application note for a complete understanding
    & o, e$ J* X; v, `3 E# p! N9 N
  21. of the device.7 v1 G( x8 Y% L5 Y5 O/ R! i
  22.   `1 y( G) n  F1 t
  23. " T" ]9 m% p4 F+ \- y, ]% E9 W6 n
  24. Device Communication Protocol(pinout related) functions:
    ( }; B5 T+ i( t% Q6 A
  25. $ N1 M5 c1 P. _; }: _
  26. Functions                                    Function
    1 F# B3 X7 n  V* s% N
  27. ------------------------------------------------------------------
    # s6 @' r" R2 M
  28. init                                        Initializes clock to set up mode 0.
    ) h1 Q+ t0 C# ^# M5 L
  29. Send_Byte                                Sends one byte using SI pin to send and : k7 V8 Z- ?+ J" y
  30.                                                 shift out 1-bit per clock rising edge8 }1 y. {( Z! H3 K/ p5 M* O
  31. Get_Byte                                Receives one byte using SO pin to receive and shift $ k- }2 W+ j7 c
  32.                                                 in 1-bit per clock falling edge
    # O7 ~! }9 M5 D, i( e6 K
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    0 `' a4 N' u; d& M6 l
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    ' c' @5 R* {5 [" }7 J
  35. CE_Low                                        Clears Chip Enable of the serial flash to low6 v/ h% s5 x1 w% O8 h, M; b1 o
  36. Hold_Low                                Clears Hold pin to make serial flash hold( E5 p+ R1 o  h/ v% @
  37. Unhold                                        Unholds the serial flash
    ; C! T' l6 z- H. Q/ x. S9 s3 w
  38. WP_Low                                        Clears WP pin to make serial flash write protected' |  M2 M' }$ U# j" r/ D
  39. UnWP                                        Disables write protection pin
    3 r5 C7 J6 `) @, b. E& x
  40. 8 }( U8 @& q9 z* A) V8 u
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code! Z8 q0 L) v( ?+ _" r0 Y
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your  ]7 r) J" x" ?# N" J* d
  43. software which should reflect your hardware interfaced.          
    $ u0 H# j: W; t6 |

  44. % Y$ Q8 R- Q& y2 m
  45. ( w; @; q( U( ]3 j$ f
  46. Device Operation Instruction functions:  F" G  _/ A2 N  ?
  47. ( ?9 h. f4 R9 O5 }) V* P9 o
  48. Functions                                    Function
    7 H. P. v, Y! L$ o' x& s# O
  49. ------------------------------------------------------------------* p: S# k. ]/ F/ h0 v
  50. Read_Status_Register        Reads the status register of the serial flash4 I/ x, G) j! x
  51. EWSR                                        Enables the Write Status Register3 n5 I% }  {4 f# \
  52. WRSR                                        Performs a write to the status register: Z7 O3 F/ u) R0 k' r4 F
  53. WREN                                        Write enables the serial flash
    * `6 }- \( u& \1 b7 {5 F3 E' E
  54. WRDI                                        Write disables the serial flash9 ~' f" N2 n# R# [, r
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    & L# R" S3 D3 q
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    3 l( y# K/ B* G+ P: N5 G) [
  57. Read_ID                                        Reads the manufacturer ID and device ID, R* L5 w  L9 X3 b8 E/ p1 Q
  58. Jedec_ID_Read                        Reads the Jedec ID2 H+ W! L. I5 P9 P/ w
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    . k2 y, [0 c# P; |  A4 p" L6 ~
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)) G2 i/ x7 E6 L6 Y% x
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)( P$ `, x# c5 e" J5 t$ v7 o6 u0 [# J
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    # ~1 J9 z% Y' H4 O% |; i& D/ a) F7 f
  63. Byte_Program                        Program one byte to the serial flash# ^! Y3 G0 H& b5 h0 |% B
  64. Auto_Add_IncA                        Initial Auto Address Increment process" j3 L" d, y6 B4 M6 \
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation0 a) S1 c* E7 |: N
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    3 E0 j  F! [& C0 O: g2 Q
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY! R% M2 x$ o3 d8 x
  68. Chip_Erase                                Erases entire serial flash
    & i9 h) M3 F9 v, P5 O
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash7 w6 I1 s7 E) @5 Y$ M
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash. _8 [: P+ O1 a" N! l5 d$ g) N& |* b
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    # d& @0 a$ x; K
  72. Wait_Busy                                Polls status register until busy bit is low. c) ~" i2 e" \- E. f, B$ n8 W9 P
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming( q. T, @4 c5 j
  74. WREN_Check                                Checks to see if WEL is set9 E) `$ M$ A; ~! h
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set  n# ^7 l; Y4 U. E
  76.   C( e  U9 V) E! p( E/ P$ z
  77. ; |- b! \' ]4 j6 F
  78. " q: ^: `' t7 x5 c( N
  79.                                                                      
    2 a! K$ n$ z4 k$ J7 `& J
  80. "C" LANGUAGE DRIVERS 4 J$ z/ d8 V! r% g; j. U1 D, y- ?

  81. 8 V: G2 z6 a& g
  82. /********************************************************************/; Z% U5 q. U7 Q3 R
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    / n# L, R- w# ~9 ]2 L
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */  _" e" u6 J( e
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    & v- r3 p5 P! G2 X6 E' ?; W
  86. /*                                                                  */
    . B; P9 b7 G0 \6 C
  87. /* Revision 1.0, November 4th, 2005                                                                          */   ' W# c. f; g% `; z* |
  88. /*                                                                  */
    # l# }, G: F0 ^& L2 x" ^0 B
  89. /*                                                                                                                                        */
    2 J. |- W5 L& i
  90. /********************************************************************/
    " |& H' v0 k  j. a* i
  91. & W5 g- A& a* K) t9 V5 @: F
  92. #include <stdio.h>
    ' k: e$ O+ `( J
  93. #include <stdlib.h>
    ' Y) H5 D0 y' o2 y& {* n9 e

  94. 5 \# l9 y8 R3 ~; y7 K
  95. /* Function Prototypes */
    7 E2 }5 F( c0 f3 d) O8 `
  96. / D( d( q! @) p/ S0 R  q
  97. void init();
    : t# n# l6 j4 ~4 {0 n$ p
  98. void Send_Byte(unsigned char out);  p3 ^+ R1 \/ j& ]$ z; J
  99. unsigned char Get_Byte();
    , k0 r" D' q5 C8 J% y: O& S1 A3 X
  100. void Poll_SO();
    # q0 q" x: H% t) u+ V8 o1 I; v
  101. void CE_High();
    * l) [* S$ w: p& x
  102. void CE_Low();
    # }: e3 Q( X; W) h6 |$ ?8 c
  103. void Hold_Low();! P, H+ p) i! V% B6 [) ^; E
  104. void Unhold();
    5 G. V5 U* V# }! L* Q' f' @3 g
  105. void WP_Low();
    * c4 x4 A& I8 b
  106. void UnWP();
    3 h8 X0 z( w6 |4 R& a
  107. unsigned char Read_Status_Register();! w- G4 z, l: c4 a
  108. void EWSR();3 x$ X  H  y, N# d8 ]; @
  109. void WRSR(byte);
    4 {: l& k# W3 c. N
  110. void WREN();5 U9 R' \6 Y9 u0 I9 A
  111. void WRDI();1 |# p0 _! J4 u9 w9 x( D
  112. void EBSY();$ P& L2 V& A+ \" H, C
  113. void DBSY();
    0 n& x  I: l8 z3 \8 f6 p
  114. unsigned char Read_ID(ID_addr);
    * t  `* l0 r1 ^" f/ l9 ?
  115. unsigned long Jedec_ID_Read();
    2 Z" I$ z: s; s
  116. unsigned char Read(unsigned long Dst);
    , n' p5 l) M1 w/ d* R" `
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    " K- u/ X1 F/ V! @1 U2 _
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    0 g+ L! G, ~% s, C
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);1 i' q" ]( W# M  X# Q# M/ w
  120. void Byte_Program(unsigned long Dst, unsigned char byte);: A# k1 g$ t' z$ p. m; P
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    4 V- a/ e' ~) Q5 }, |  I  h
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    & A8 ]* t+ Y- Z5 N# b* s* @7 T9 t! N7 E
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    9 A9 g5 n: X# }
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);7 G* t# z# S  X2 u* Y  z; V1 _8 ~
  125. void Chip_Erase();
    - B! D/ X+ j' Z
  126. void Sector_Erase(unsigned long Dst);8 q& y1 P6 l9 L1 M' M( O
  127. void Block_Erase_32K(unsigned long Dst);
    : ~- x, }+ x1 x
  128. void Block_Erase_64K(unsigned long Dst);% I; G. f5 u( _$ n* l, x
  129. void Wait_Busy();) _5 B# X5 _$ i8 k9 U
  130. void Wait_Busy_AAI();  @& r6 G3 b3 @# V$ Y. j
  131. void WREN_Check();
    8 y8 o+ c/ I2 v
  132. void WREN_AAI_Check();/ W/ l/ a. r; j. N% e

  133. . n2 C( {8 m& Q4 I8 z$ c9 x% }
  134. void Verify(unsigned char byte, unsigned char cor_byte);( Z. o" S, l' r

  135. 1 E3 {! |1 K1 \* c6 e! v4 T
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    8 S; V7 X' C$ K4 {
  137.                                                                                 /* to upper RAM area from 80H - FFH */% T- G' W5 g$ H% f5 n; K) @( |% `( a& `

  138. $ W2 C9 ]7 v) B& ^8 s
  139. /************************************************************************/, s* m7 v2 B/ d7 b& H
  140. /* PROCEDURE: init                                                                                                                */7 Y8 H' L, ?+ ~' a6 ?
  141. /*                                                                                                                                                *// z/ E$ e; ]8 j$ \0 S+ ~
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    7 q: {+ [5 j# r- s/ Y5 \% N( b
  143. /* setting up mode 0.                                                                                                        */
    ' a3 n6 O, y/ k! Z7 e  }  ^, T/ s
  144. /*                                                                                                                                                */
    $ A3 {5 E  d; o- G
  145. /* Input:                                                                                                                                */
    ( v& W2 |4 J5 @. S/ C1 g; @) w
  146. /*                None                                                                                                                        */+ `1 d$ R( A! u
  147. /*                                                                                                                                                */3 |( V* G; r0 X$ ~, w
  148. /* Output:                                                                                                                                */
    1 a3 @) C; B- f: ]( z
  149. /*                SCK                                                                                                                                */
    1 \9 e; n" ?8 ~
  150. /************************************************************************/- z0 y, `+ c7 a$ g
  151. void init(): _/ R7 a' W0 D7 N& y' a
  152. {
    / }* V+ G+ Y) f
  153.         SCK = 0;        /* set clock to low initial state */
    ) m7 u7 R6 L/ A" [! ^. P+ t
  154. }
    9 u# _/ U& w, Y2 l5 h, H' b9 K

  155. ; J4 t* `3 Y! x1 M/ W
  156. /************************************************************************/7 Q+ i0 g9 B; Q9 w& j9 q& j; V& {. \7 |8 n
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    # Q1 r% M* ]' b2 f. @7 L: |6 E
  158. /*                                                                                                                                                */
    8 k- V" \( k3 ^
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    - ]7 y: p3 f; h6 O
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    9 K5 S' E) n0 L7 R' M8 E$ z
  161. /*                                                                                                                                                */
    7 H4 E. x- Z2 F# i6 @: |8 E: y
  162. /* Input:                                                                                                                                */  M! O, x% W9 a* R% ]6 Q* ~* N
  163. /*                out                                                                                                                                */
    % B. b5 W7 H! M5 u9 n  N5 ]
  164. /*                                                                                                                                                */
    4 w9 ^3 Z5 u/ \& v0 S, f; T
  165. /* Output:                                                                                                                                */. H+ f5 ^! y, t8 W% b* J$ C
  166. /*                SI                                                                                                                                */
    ( ?7 |4 c7 D. Y4 `+ S
  167. /************************************************************************/
    4 P# L& x  |- J9 S- i& D
  168. void Send_Byte(unsigned char out)
    : ?9 R0 W: I* d# s4 H1 f
  169. {
    1 p+ ?( y( m1 z; G& J7 R0 ~
  170.        
    + u3 [# _6 Q, I- [7 M
  171.         unsigned char i = 0;
    * u. l' f! Z. Z; P$ n$ ^( C
  172.         for (i = 0; i < 8; i++)/ i+ p. e) K/ m! W4 b3 I
  173.         {& U& t( T: W8 g* Z: F0 O
  174.                 ! c, L( N- {7 Z
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
      X" }2 t8 r; f4 T: V$ j/ l6 k
  176.                         SI = 1;  T1 F! ~7 \8 Z' u1 M3 _) U3 [6 W
  177.                 else# g" L6 t) W$ y. U. I
  178.                         SI = 0;                                /* if not, set to low */& |6 Z4 Q( A& ^" n) r5 N! e
  179.                 SCK = 1;                                /* toggle clock high */; ^1 R  y$ _, z" s1 E
  180.                 out = (out << 1);                /* shift 1 place for next bit */! o4 S+ A! ]8 i
  181.                 SCK = 0;                                /* toggle clock low */' K, p' S( [, D! H9 b4 U
  182.         }- L+ H6 f  [! ~! }' O* l2 q4 c
  183. }
    ( R% \. }2 Z( O  J: v

  184. 0 r4 E4 w3 R: R
  185. /************************************************************************/
    ' b$ E, J. |3 k. b7 U8 @3 }# A
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    ' m6 {# e8 a1 B# Q' n% R+ c
  187. /*                                                                                                                                                */9 b& V0 \* i/ f, ^! D
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    ! t  q% J8 I( ]1 [
  189. /* edge on the SO pin(LSB 1st).                                                                                        */, w: }; R8 S: L$ `: l
  190. /*                                                                                                                                                */
    % u1 ]& C- @$ l+ G
  191. /* Input:                                                                                                                                */$ L6 i4 x9 ^6 g  X
  192. /*                SO                                                                                                                                */
    # Z6 Q& \' Y: }+ }% u% h5 m
  193. /*                                                                                                                                                */
    7 w( C* z/ L. H9 m3 @
  194. /* Output:                                                                                                                                */
    $ `% g" v6 X2 Q. Q  V) j1 ]
  195. /*                None                                                                                                                        */
    , r" H- B9 E( V0 s4 B
  196. /************************************************************************/
    ' d1 V9 t& l3 p6 A; W
  197. unsigned char Get_Byte()
    1 b$ h7 T7 I# u$ V
  198. {: d$ e$ j& D4 h6 o5 g! K# J& @
  199.         unsigned char i = 0, in = 0, temp = 0;
    % X, G; T4 ]) L0 k1 J( X3 G8 U2 W# f1 ^
  200.         for (i = 0; i < 8; i++)5 f5 j% ?2 p6 b0 j0 t" x
  201.         {
    2 h# K0 P, c+ n; T* q/ h
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    # G; _+ K) u& c# L, s& }' h
  203.                 temp = SO;                        /* save input */; {# s, X) H: b- y* G
  204.                 SCK = 1;                        /* toggle clock high */9 j) @4 r5 z1 ?: s, v/ d8 `
  205.                 if (temp == 1)                        /* check to see if bit is high */
    . J' e! h2 f3 ]. @' [
  206.                         in = in | 0x01;                /* if high, make bit high */
    ( L& ]9 g  |! m: E& Y4 S0 }2 |

  207. & C# S$ ?; p! i  y
  208.                 SCK = 0;                        /* toggle clock low */
    / {. g( A3 k& }7 l( M3 v7 u

  209. 0 a* o1 n7 H$ e6 y# q2 w& T0 L
  210.         }
    5 M5 f2 @4 Q4 v) Q4 m
  211.         return in;
    0 N4 {, {) p3 `- X* K. \
  212. }
    % U) J! G  n% s; J# g

  213. & N+ e9 l* x/ D! S
  214. /************************************************************************/8 E. C, t- a' b! m. Z& i7 a7 L
  215. /* PROCEDURE: Poll_SO                                                                                                        */1 J1 V; H+ i/ \3 V  n' v3 H( @9 M
  216. /*                                                                                                                                                */
    ' y$ _+ p# ]! [/ o
  217. /* This procedure polls for the SO line during AAI programming                  */
    4 _9 x7 d/ p7 K* H( ]. L
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    4 s" s" m/ G7 s* ~/ M
  219. /* is completed                                                                                                                        */
    2 S# |/ c- C0 n2 x- I
  220. /*                                                                                                                                                */- ^" ~8 u/ {0 l7 d+ n
  221. /* Input:                                                                                                                                */5 N: J$ ?5 \7 f" v. I
  222. /*                SO                                                                                                                                */% V2 T, B4 x3 M# H
  223. /*                                                                                                                                                */
    . l# m, [) ^1 V8 E1 \. k- N
  224. /* Output:                                                                                                                                */% B! D! g: T, m1 L9 ~* h
  225. /*                None                                                                                                                        */0 a; |1 w* G1 G* Q+ N
  226. /************************************************************************/
    8 \5 o% m8 J$ Y; o8 t
  227. void Poll_SO()
    4 G* t* W) h, A* l. Q9 n+ W( k
  228. {
    2 Q; d$ l: r$ i: A1 S: L$ J' @" V
  229.         unsigned char temp = 0;
    1 j( a. Y* y6 |
  230.         CE_Low();
    1 z+ z/ {; n# M( i9 x
  231.     while (temp == 0x00)        /* waste time until not busy */6 {/ N: x" [  G# V1 G
  232.                 temp = SO;
    / s% S# D8 u$ T3 {3 u4 Q1 d/ Z' H" s2 H
  233.         CE_High();1 P/ Z8 }1 ^7 [. P& H) X
  234. }
    & A( W# m* w0 z

  235. $ Y4 ^8 S) C# R0 u, n' F
  236. /************************************************************************/
    8 B9 }: P$ c/ c& ~8 e
  237. /* PROCEDURE: CE_High                                                                                                        */& G7 ]/ l, J# O" `1 O& G
  238. /*                                                                                                                                                */
    8 o; r5 ?, `- o; N0 b8 J
  239. /* This procedure set CE = High.                                                                                */- u( F; l, ^' ^6 l5 t& s
  240. /*                                                                                                                                                */
    . i7 ?0 C" z; Q. m+ b7 \' v: s6 ^
  241. /* Input:                                                                                                                                */
    ! ~$ R2 ~1 F$ \# g+ w& R& G8 I
  242. /*                None                                                                                                                        */
    , b8 J* ~" t4 D# s5 B! G4 {
  243. /*                                                                                                                                                */3 A5 E& K3 e  R1 C* K% g- J4 v
  244. /* Output:                                                                                                                                */
    # }9 m8 C* R+ ~! _: V
  245. /*                CE                                                                                                                                */
    8 `" g; T+ c8 K. W: F/ E2 ?
  246. /*                                                                                                                                                */
      Z; Y4 S) S+ I
  247. /************************************************************************/3 j7 @4 ~( k8 m: b0 W& w
  248. void CE_High()
    8 [8 k+ [! R1 n7 z
  249. {8 m6 Q/ b2 \! I, s2 S/ |5 b4 C8 p
  250.         CE = 1;                                /* set CE high */- {9 L  Z4 u: [3 ~; k& G" U( \- y
  251. }
    - Z/ M8 Z4 ~0 n5 o( A7 }8 _
  252. 2 F- y- }. D9 Y# z- F
  253. /************************************************************************/, `4 K* [3 A$ ~& h
  254. /* PROCEDURE: CE_Low                                                                                                        */
    # p3 ^( s3 f3 y+ i8 _
  255. /*                                                                                                                                                */
    3 P4 V/ h& ^$ t; W% F5 e
  256. /* This procedure drives the CE of the device to low.                                          */8 ~: o0 u# I" n
  257. /*                                                                                                                                                */
    - B3 @5 _; ?. ]4 v/ _
  258. /* Input:                                                                                                                                */; M4 b  H* L3 R& a1 T+ i' v
  259. /*                None                                                                                                                        */$ d7 a; n* @! |6 m. O
  260. /*                                                                                                                                                */0 d( z. [  Z/ |; {
  261. /* Output:                                                                                                                                */% G% `9 \, @, H
  262. /*                CE                                                                                                                                */6 M& n% Q/ y' l/ h7 C: c
  263. /*                                                                                                                                                */+ e. ^" g: D4 l* v! E5 @
  264. /************************************************************************/
    6 @; v' T4 V, w: e$ L  A
  265. void CE_Low() , ?* h9 Q- A. [6 W5 X. L3 g; ~& y# }8 v
  266. {        5 l/ n4 C5 B) t& l! e
  267.         CE = 0;                                /* clear CE low */5 C9 G% Q" D+ F3 T' u5 M# a
  268. }: N; T( E  X! ^4 z7 ~" k2 T

  269. : M) A( _# p1 [/ V$ _
  270. /************************************************************************/9 t! {5 a3 v6 H
  271. /* PROCEDURE: Hold()                                                                                                        */
    3 B! w; B& L6 W, ^
  272. /*                                                                                                                                                */
    ) m+ c0 Q" y1 @: G8 C2 g8 p' r
  273. /* This procedure clears the Hold pin to low.                                                        */
    , G6 s/ u- j+ q
  274. /*                                                                                                                                                */7 H( w4 s* m# X7 k+ q) Y
  275. /* Input:                                                                                                                                */
    7 c0 ?" o) v9 O- Y6 K3 O
  276. /*                None                                                                                                                        */
    ( y: q$ n' G: H. ?: \/ g
  277. /*                                                                                                                                                */4 e6 y- P" q4 M, M* o
  278. /* Output:                                                                                                                                */
    2 Y3 K& Y3 u* O# p
  279. /*                Hold                                                                                                                        */+ \& N2 q1 O1 F) g% L
  280. /************************************************************************/
    0 ^, c! E: e9 S1 t  w+ s
  281. void Hold_Low()
    + h7 j; b9 G- j1 q0 Q
  282. {5 J- ~6 P, W6 `7 {
  283.         Hold = 0;                        /* clear Hold pin */
    ! Z8 ^# K6 K5 F( z
  284. }
    ! d6 W3 N2 u# K+ q  P/ N; `( V
  285. 1 C" v+ D0 f/ w7 O: t
  286. /************************************************************************/0 s, ?& _8 y6 }2 q* G1 c9 j6 T
  287. /* PROCEDURE: Unhold()                                                                                                        */
    2 o# h. ~0 o; Z0 k8 H' N
  288. /*                                                                                                                                                */
    3 O$ q& X6 l: j0 y
  289. /* This procedure sets the Hold pin to high.                                                        */3 v5 Y& J1 W  k& X
  290. /*                                                                                                                                                */" b4 z8 y1 n: C, ^; ]
  291. /* Input:                                                                                                                                */$ l' ^0 W$ U: D, j6 C
  292. /*                None                                                                                                                        */
    " y! B5 c" s4 ^! f# ?) W& X
  293. /*                                                                                                                                                */2 V+ _5 @* X' f; a
  294. /* Output:                                                                                                                                */9 w$ r4 q( \0 e: y' w! O
  295. /*                Hold                                                                                                                        */& S' ~2 Z  i  _3 @/ W
  296. /************************************************************************/6 J" H- K" ]& x- i1 C9 l" j
  297. void Unhold(): D1 v2 D( l8 _  y$ ]
  298. {8 j6 T3 W6 c; r( S7 [* M4 _
  299.         Hold = 1;                        /* set Hold pin */
    / {% k1 d( y( {3 h6 c
  300. }: T# l5 \3 d0 B& p1 w
  301.   ?1 c9 Q1 s# X7 T$ F' p
  302. /************************************************************************/3 R/ Z. X1 w& t/ L5 S. [
  303. /* PROCEDURE: WP()                                                                                                                */
    7 x7 U8 F( J$ C1 W) [; T. N9 d* o
  304. /*                                                                                                                                                */
    1 U) q# [& _" S/ v7 N
  305. /* This procedure clears the WP pin to low.                                                                */7 _7 G! n+ C6 h5 a9 A$ g1 ~
  306. /*                                                                                                                                                */
    4 Z- h* \5 K* y- I" n# [
  307. /* Input:                                                                                                                                */
    - T! A) {6 w& x7 U
  308. /*                None                                                                                                                        */
    # `7 `1 J. \9 I- s3 n
  309. /*                                                                                                                                                */5 y$ o! q5 r7 P+ L# Z
  310. /* Output:                                                                                                                                */
    / `' P& g, ~' v& S$ V
  311. /*                WP                                                                                                                                */5 T" O$ H. h, U8 d
  312. /************************************************************************/
    0 Z5 }: W1 N# I! R/ k( ?7 I
  313. void WP_Low()
    : ^+ U# ]. u& P7 ~' c, J4 X
  314. {. t* L6 i- K$ ^: `3 h$ [! t, I
  315.         WP = 0;                                /* clear WP pin */  ^  j1 T$ M; V! X7 g/ a
  316. }
    - o: _# ]" P+ t$ W5 b/ R, @( A
  317. 6 |, k' w. C  Z& {8 O
  318. /************************************************************************/
    $ p0 K) Q8 S4 y8 e% S+ i; R
  319. /* PROCEDURE: UnWP()                                                                                                        */
    ; D6 ?4 {8 Y9 Y7 F: {5 p) Z  J
  320. /*                                                                                                                                                */
    3 s! b( i- J" p$ _
  321. /* This procedure sets the WP pin to high.                                                                */. N+ F8 u5 Z/ d$ H
  322. /*                                                                                                                                                */
    8 N  ]% k0 f( X" d& `' M& {% F2 [. t
  323. /* Input:                                                                                                                                */
    8 ~% ~  C% g( f2 A  i; O
  324. /*                None                                                                                                                        */' C3 C" E5 a; q
  325. /*                                                                                                                                                */* s$ |* W" C4 e& M$ a1 O# A% S: P
  326. /* Output:                                                                                                                                */* O& m* x1 ]* E8 _, k
  327. /*                WP                                                                                                                                */6 U/ u! H3 l7 b0 G4 M) ]- W
  328. /************************************************************************/
    2 H3 D' o6 J" d' L0 y0 Z( ^4 X
  329. void UnWP()
    & ~- r9 A( j5 O9 z4 P
  330. {: F0 m! e" C8 @- L0 T- H4 i
  331.         WP = 1;                                /* set WP pin */
    1 [: Y! m/ |& i: `: \
  332. }
    * U- l7 _, z, k# w3 i. @8 E& J5 L
  333. 3 E: l, l6 x5 Y' A, q7 d
  334. /************************************************************************/8 X# s/ ~, n7 d  ~
  335. /* PROCEDURE: Read_Status_Register                                                                                */. L9 {3 |# ^% x" Y. ]
  336. /*                                                                                                                                                */9 \+ O" i! b3 H; b! @
  337. /* This procedure read the status register and returns the byte.                */6 k& X0 {$ H) f/ g0 W8 n* q
  338. /*                                                                                                                                                */+ x8 _- P, I; V. R
  339. /* Input:                                                                                                                                */: ~9 f5 ~( l! w$ C4 I8 y
  340. /*                None                                                                                                                        *// l& j7 t7 C3 t1 V6 ?" s
  341. /*                                                                                                                                                */8 d" y& Y6 v& U+ i
  342. /* Returns:                                                                                                                                */
    $ p& y+ S* C- @- |# X
  343. /*                byte                                                                                                                        */4 |& y* V' }3 C! a) @9 j0 G$ C! u, j
  344. /************************************************************************/$ U1 B; F$ [) Y4 S- W4 n# |
  345. unsigned char Read_Status_Register(). Z, \: k: Q% G- L
  346. {
    . q9 ^! K6 X: W6 N
  347.         unsigned char byte = 0;
    # P6 }5 h+ n% O
  348.         CE_Low();                                /* enable device */
    / ]6 W: |' w1 S% y4 ^$ ], s4 E
  349.         Send_Byte(0x05);                /* send RDSR command */: [# c( V* x8 e# L1 y. u, W7 Y
  350.         byte = Get_Byte();                /* receive byte */+ v7 b% a1 Q$ F" d
  351.         CE_High();                                /* disable device */
    + o2 d+ U+ P8 R( H
  352.         return byte;8 r5 [7 M$ _; P. d6 X5 u
  353. }% h( Q! D' Q$ O9 k

  354. ; _0 f9 s4 W* P% {( i! Y
  355. /************************************************************************/0 Z% C1 t3 u- v7 ?' I
  356. /* PROCEDURE: EWSR                                                                                                                */
    - A& m0 A2 l5 G) s7 s+ N
  357. /*                                                                                                                                                */: f. A8 g, U5 X, T0 O
  358. /* This procedure Enables Write Status Register.                                                  */4 ?) }8 a7 ~: O) ]  a
  359. /*                                                                                                                                                */
      ?; I/ [! Z0 j, v% z
  360. /* Input:                                                                                                                                */
    3 G  H) m& L' n- d, G2 ~
  361. /*                None                                                                                                                        */
    - z8 w/ h: e, p% q: B' L
  362. /*                                                                                                                                                */
    , o) h& u. W/ w( U' J  i
  363. /* Returns:                                                                                                                                */
    ' w; z1 l- Z. t
  364. /*                Nothing                                                                                                                        */
    + V9 i1 o# Y9 @2 `0 N
  365. /************************************************************************/9 q" V0 s0 j5 q0 n* \' y4 z1 `
  366. void EWSR()
    - ?: D# P. j( \. x: M8 m
  367. {
    $ U7 A; ^& r( }* T2 c! m" O
  368.         CE_Low();                                /* enable device */# S3 R0 Z( R/ L; @! d. ~
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    % S$ e! A0 c' }: g6 f( j6 u& o
  370.         CE_High();                                /* disable device */& G8 Q6 |+ l* e- ?
  371. }  ~! ~" j$ ?- P

  372.   G; f. u0 T) w5 p/ o* l
  373. /************************************************************************/
    ) U' U# Y1 U- |' ^- y  a" y0 h0 _: y
  374. /* PROCEDURE: WRSR                                                                                                                */" j- s3 I5 K- {; K! \" F
  375. /*                                                                                                                                                */$ \4 Y6 k: s8 |3 x6 Z$ m( l, r
  376. /* This procedure writes a byte to the Status Register.                                        */) d. L. r; i7 k% K- r
  377. /*                                                                                                                                                */' d& }* m8 `1 y% p) V0 Q
  378. /* Input:                                                                                                                                */
    - A+ ]' x) Z1 h6 r6 e2 i
  379. /*                byte                                                                                                                        */7 D! f3 }7 J1 {3 \/ e  K
  380. /*                                                                                                                                                */' ~8 ], ?' }7 l3 c+ L$ P1 f
  381. /* Returns:                                                                                                                                */4 K3 S% d8 \8 p( {" `+ I
  382. /*                Nothing                                                                                                                        */( r8 F$ L- T5 O
  383. /************************************************************************/
    3 W# V8 ?6 J" y
  384. void WRSR(byte)2 ?! F( S: L. O5 X# d( B( Q' x
  385. {
    : o; G1 w3 T  t# k) ]- A; M+ y+ O8 h
  386.         CE_Low();                                /* enable device *// Z! ?1 {& ]! @
  387.         Send_Byte(0x01);                /* select write to status register */
    * t4 R: r7 i5 Q  O& g( C6 I
  388.         Send_Byte(byte);                /* data that will change the status of BPx 9 t' Y* O. y0 `4 K
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */# }2 J5 Z$ J* k
  390.         CE_High();                                /* disable the device */
      Y7 g2 E$ g6 d" p0 o6 W. I
  391. }
    $ c6 g* `: a3 t# ?

  392. % H' l  }6 r2 f. h+ T
  393. /************************************************************************/; }2 U8 b: s7 \% F
  394. /* PROCEDURE: WREN                                                                                                                */
    % Z2 M" e1 K! u( J
  395. /*                                                                                                                                                */$ ?. |0 a7 \% @3 E! u1 Y
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    ( o. G, N0 T" D. N
  397. /* to Enables Write Status Register.                                                                        */8 B7 \; m* e5 K$ \: x0 A2 `
  398. /*                                                                                                                                                */2 n& _3 D/ ^* n6 Z4 {
  399. /* Input:                                                                                                                                */
    ; R6 }5 {1 o7 z8 E" q2 F3 c
  400. /*                None                                                                                                                        */
    5 c7 `! n: G) c# Z1 }4 u
  401. /*                                                                                                                                                */6 T5 g1 }- T" X  x4 u# X
  402. /* Returns:                                                                                                                                */$ Q2 x* _" l4 m0 L! o2 ~
  403. /*                Nothing                                                                                                                        */9 c" H8 Y4 E$ r. T1 O9 |$ Z0 `2 L
  404. /************************************************************************/1 O8 A  V$ y9 F# J
  405. void WREN()9 U4 W* V4 Y/ w7 o
  406. {# E( z: `/ l" g; v& \3 J
  407.         CE_Low();                                /* enable device */+ l5 Q; g( n' j0 L! h' z4 \
  408.         Send_Byte(0x06);                /* send WREN command */& n% m+ x9 X) k8 Y; O% `
  409.         CE_High();                                /* disable device */& ~- N. b# H5 V! M% v
  410. }
    1 Y/ a+ \# r: A& I

  411. " \0 q6 \% Y& V& X
  412. /************************************************************************/
    ; F& _* U( a( l, P$ k" D3 F
  413. /* PROCEDURE: WRDI                                                                                                                */
    : H# m( ?: ^6 N7 I/ i4 l! b
  414. /*                                                                                                                                                */
    $ D3 c: _$ M3 L5 h6 o" |4 j
  415. /* This procedure disables the Write Enable Latch.                                                */
    2 x3 S$ W9 o* D* v) J( X$ G) k* V
  416. /*                                                                                                                                                */
    ) C" S* O3 I9 h5 D3 Q+ r. a9 z
  417. /* Input:                                                                                                                                */
    : m) P1 U% W* S5 s( H, i3 |& x
  418. /*                None                                                                                                                        */& S8 g! w! ^+ T7 n* F6 R) h
  419. /*                                                                                                                                                */
    / g3 h) S! d* c" P$ v9 f
  420. /* Returns:                                                                                                                                */' @6 v3 M$ G! Q
  421. /*                Nothing                                                                                                                        */
    : P" L8 a6 B5 \4 n( ]
  422. /************************************************************************/* E# H: H: e5 R* o: F
  423. void WRDI()
    # ^) b. C2 m" w, _/ B
  424. {
    4 F& B9 U. w% @8 s# R# |9 j
  425.         CE_Low();                                /* enable device */3 Z6 q7 [% E1 O
  426.         Send_Byte(0x04);                /* send WRDI command */" h8 y8 g6 Y0 c+ r. f
  427.         CE_High();                                /* disable device */
    ( J! u: D& @: ]( R" U* X
  428. }5 ?( N' Q( c+ x! N3 V# w/ Y* S
  429. . r' J! z. u9 }; |
  430. /************************************************************************/
    " y( l/ M1 z+ h, z* r' N5 V% J
  431. /* PROCEDURE: EBSY                                                                                                                */
    & e/ G! I* m7 ^+ U/ @2 R; g( }. D$ O
  432. /*                                                                                                                                                */0 `8 I% P. I) S3 G3 G- t0 O
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    + h4 [& }2 R$ O4 }7 \
  434. /* programming.                                                                                                                        */
    & y) K4 W0 G, I5 T1 I
  435. /*                                                                                                                                                */
    ; }5 S) s6 @2 o7 C
  436. /* Input:                                                                                                                                */
    ! g5 p" @9 v6 \# H
  437. /*                None                                                                                                                        */
    , f& \" L  R) E% A
  438. /*                                                                                                                                                */, B/ R& ?) S- z8 ]9 w8 q/ v
  439. /* Returns:                                                                                                                                */
    / ?! c9 {5 h% z
  440. /*                Nothing                                                                                                                        */
    3 m  J- L! L4 Z
  441. /************************************************************************/& X) f% G% T% `1 A: T
  442. void EBSY()1 m% H' O0 d2 w! ]
  443. {
    % R1 p, m& K" ~$ `; ?7 s1 B* E
  444.         CE_Low();                                /* enable device */) F0 x4 u  M3 H+ R2 K4 z
  445.         Send_Byte(0x70);                /* send EBSY command */+ H" X8 n- L( g0 n. m9 J
  446.         CE_High();                                /* disable device */! b' i! G1 [, j; ]. j
  447. }5 R+ g4 A* F% m9 `

  448. + [6 I" i* q) Q* j% [2 V( T1 o  D
  449. /************************************************************************/
    6 r: d8 R" N9 K8 Q+ L
  450. /* PROCEDURE: DBSY                                                                                                                */6 ~/ q3 U  c  M7 s4 P
  451. /*                                                                                                                                                *// V3 ~$ J; Z/ p8 X% ~: q
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */9 m: H/ t  S# B$ H$ H( b  {
  453. /* programming.                                                                                                                        */9 D( Q1 J8 z! X% Q- J+ `
  454. /*                                                                                                                                                */
    ! a, z/ h2 |8 G( I) z
  455. /* Input:                                                                                                                                */
    , p, z4 i+ a/ s' u8 N# I( R4 ^
  456. /*                None                                                                                                                        */- W- v3 s4 ]5 f6 y  T4 N0 {% E
  457. /*                                                                                                                                                */
    ; n2 p* p" l' Y& C0 c
  458. /* Returns:                                                                                                                                */
    ' T' {8 d7 T% K8 _6 l& O1 {+ P: z
  459. /*                Nothing                                                                                                                        */
    + a; n* x  U' p9 v6 B  A
  460. /************************************************************************/
    % {; g! M6 V9 ^( ~  D. ^5 e3 ~
  461. void DBSY()3 b0 M0 `3 z$ L+ J
  462. {; j3 N. z. {  R2 z; q
  463.         CE_Low();                                /* enable device */& c& c4 D6 P5 w. x6 s/ [
  464.         Send_Byte(0x80);                /* send DBSY command */  [# U& s* \6 z
  465.         CE_High();                                /* disable device */
    1 S* M9 Y3 e% x
  466. }
    6 o+ c* [" Q7 a; _" \
  467. 0 q( \) d  O4 _0 C: |  [, _% C: I
  468. /************************************************************************/
    ! N! W, {% _% N8 \( M# r
  469. /* PROCEDURE: Read_ID                                                                                                        */
    9 _6 G' F4 v8 K7 b& q
  470. /*                                                                                                                                                */
    + T! C8 r% x4 k3 t6 e1 S1 i7 X
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */. V3 C: ]+ z- ~' `# F. X- e
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */) {3 Y5 Z: i8 b6 @
  473. /* It is up to the user to give the last byte ID_addr to determine      */# p4 ^  c& S9 R0 m
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    1 n: e" T* u- w. F- U; ]
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    , _' Q/ h$ J4 _# N- x
  476. /* variable byte.                                                                                                                */- ~  x% V2 l3 Q7 k0 [
  477. /*                                                                                                                                                */+ g6 K1 i$ ^% t0 q
  478. /* Input:                                                                                                                                */
    ! @8 p: S9 o/ ~% t9 ^
  479. /*                ID_addr                                                                                                                        */
    ' C; A% ^5 m' G3 K) ]
  480. /*                                                                                                                                                */
    / S8 P4 p6 g# c
  481. /* Returns:                                                                                                                                */
    $ E7 @1 a7 S; V; ~9 U
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */  x, x( U' |( K2 ?3 p3 D
  483. /*                                                                                                                                                */
    & E2 A+ ]3 @+ H! U
  484. /************************************************************************/- z' Z6 \/ A6 x- l2 _2 A- k
  485. unsigned char Read_ID(ID_addr)
    2 _, d# z" P* T. R7 F% z- ?
  486. {
    3 Y6 Y7 R, v/ l' X% y9 U
  487.         unsigned char byte;
    : Q+ x9 w; _! B$ g/ ?* _; p8 R3 [
  488.         CE_Low();                                /* enable device */- w% o6 t3 H+ y$ `/ [& j
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */+ E/ e  C2 C+ W
  490.     Send_Byte(0x00);                /* send address */9 j3 f/ p1 w) U) c/ g- s/ @% J
  491.         Send_Byte(0x00);                /* send address */( g2 F5 E. t& @6 {& ^
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */5 C1 v! |3 G& S) j5 K9 R$ g
  493.         byte = Get_Byte();                /* receive byte */; \' ?' Z6 a& B( q
  494.         CE_High();                                /* disable device */
    % {1 S+ ]  b; V3 _8 D
  495.         return byte;0 W/ c! e3 ~) L- Q: T  h+ E& \2 K
  496. }
      T! k+ g  W/ l; |
  497. ! ~! s: P3 A; b' c5 l
  498. /************************************************************************/
    5 w5 l  q* K3 l8 ^0 b% {6 [
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */; M* L9 M) |' H2 V
  500. /*                                                                                                                                                */: P* |: @. f( k1 R
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    ! A: H; r) n( x" {' ?. [" V$ q) I  |
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    % H# b5 `2 S( X1 G6 C  l- t
  503. /* Please see the product datasheet for details.                                                  */% s% d% ~" K  n3 i% G
  504. /*                                                                                                                                                */% I) L8 @) l& Z4 \+ h+ S
  505. /* Input:                                                                                                                                */
      H  K# @# N' F9 @! y2 ?
  506. /*                None                                                                                                                        *// L' ~- J# j/ T6 u) k
  507. /*                                                                                                                                                */; Y4 @  A/ v: O+ `/ A2 F* K
  508. /* Returns:                                                                                                                                */) m2 x) h9 l! X4 w, |
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */$ q5 [! `/ U( k  G0 _9 m. Q( D
  510. /*                 and Device ID (8Eh)                                                                                        */
    , q. t4 n# |' m$ E. u
  511. /*                                                                                                                                                */1 s. G. w4 y: |& B" r' \3 [4 }0 t0 S
  512. /************************************************************************/
    % W& z1 D' v9 g# v3 `
  513. unsigned long Jedec_ID_Read()
    $ F% N' V+ M! G: T8 N( M
  514. {
    # \) \9 P9 ^4 H. U% J* y5 u
  515.         unsigned long temp;/ R! Y( x7 M" F( D, R; R0 D
  516.         0 Q4 y7 g7 L( e  Z% a5 A
  517.         temp = 0;
    * z! B, F; T' _' s- c

  518. : i) @( J  t, P% J1 r2 v
  519.         CE_Low();                                        /* enable device */
    ( G1 J; V1 E& E- `
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */) o# U1 S2 U- z0 i; }8 ]
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    ! q$ k/ |- n" |5 Y( O9 s
  522.         temp = (temp | Get_Byte()) << 8;        9 a5 b$ M8 C0 N2 W8 \& ~7 j
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */# K; D1 D; E+ K( r. `5 W' |) A
  524.         CE_High();                                                        /* disable device */
    / e* A8 c: ]6 y
  525. " \2 W1 x: m0 M% r% b
  526.         return temp;
    - X" f6 h0 `: ], v  ]( r
  527. }' q; H! {* I, p, @7 Z( D, I4 \

  528. & Q% Q& A7 ~8 @' ~
  529. /************************************************************************/$ I! |1 U) a2 h9 X. `
  530. /* PROCEDURE:        Read                                                                                                        */
    9 y9 ]% c- g! _- V: N- L
  531. /*                                                                                                                                                */               
    3 O$ n& S7 b* T6 `, g) t7 J, x& i
  532. /* This procedure reads one address of the device.  It will return the         */
    + s. i/ |, n$ F1 [% C
  533. /* byte read in variable byte.                                                                                        */
    8 B7 x: E) z# |1 d
  534. /*                                                                                                                                                */
    7 d; o. E; |7 c+ }  @4 G9 ?; Y3 T
  535. /*                                                                                                                                                */
    0 k1 }) X: c% q' X3 r$ e, P* n
  536. /*                                                                                                                                                */
    4 k' X( Q6 Y5 \% b+ a7 M, S( X( N
  537. /* Input:                                                                                                                                */8 r+ ~2 N7 m5 E
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    6 \1 {( d; n5 Z6 b* ?
  539. /*                                                                                                                                      */
    . e3 A2 @) y( y! f7 K
  540. /*                                                                                                                                                */' s" E0 K: G7 r( ~
  541. /* Returns:                                                                                                                                */# r, g% T# W* p( I! i
  542. /*                byte                                                                                                                        */! `2 @6 h4 c% g0 F* I
  543. /*                                                                                                                                                */0 v& h: B' Y) q. g7 a
  544. /************************************************************************/
    7 W* y# D- {8 a9 D
  545. unsigned char Read(unsigned long Dst) 0 O& S! q/ u! G7 ], [5 H$ u
  546. {$ t& g2 K3 p) Y
  547.         unsigned char byte = 0;       
    ' ]$ W) _4 X0 j- k' K% U7 h. Q
  548. - P  @% f& T" g0 j/ j/ W% v" C( \4 D
  549.         CE_Low();                                /* enable device */
    % x4 s. e1 x. f: w0 `
  550.         Send_Byte(0x03);                 /* read command */  I! g5 A/ u8 {; ~3 R5 i
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    & {/ r: |9 m9 F4 V" p
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));; n! V* M3 Z: G1 Z( v3 z9 M' i
  553.         Send_Byte(Dst & 0xFF);
    0 s, n* L  V8 v) K/ [$ e
  554.         byte = Get_Byte();( M- ^' P" s: [" `0 Z
  555.         CE_High();                                /* disable device */
    0 q/ n0 k/ k) V% a
  556.         return byte;                        /* return one byte read */+ M' a  U, }- j0 f
  557. }
    , R) Q" l! E" j1 h0 }

  558. + K% H( G8 _/ H& n
  559. /************************************************************************/% G: Q# P0 y) L3 Y
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    ) Y4 ?9 R9 W/ ^* `8 |. e
  561. /*                                                                                                                                                */                $ O$ u+ S& d  C& @: K
  562. /* This procedure reads multiple addresses of the device and stores                */, m2 P) B3 X1 v
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    ( a5 |; g. S/ i: T6 P% V1 P* F
  564. /*                                                                                                                                                */% ~8 ^  q+ ^8 P% Q
  565. /* Input:                                                                                                                                */
    , r- v: @1 F, l
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * z/ q/ t8 L% ?3 Z
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */! X3 }6 I* Q4 P5 x) j
  568. /*                                                                                                                                                */
    / _  [9 y4 Y0 Z+ F& {
  569. /* Returns:                                                                                                                                */) l2 u8 T  e% o" p$ T* c: }
  570. /*                Nothing                                                                                                                        */7 |6 K7 S; L' X+ T8 |( e
  571. /*                                                                                                                                                */
    + D, S1 U. V+ X
  572. /************************************************************************/
    5 J9 j+ a8 p7 L- E
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    ; v! p; b1 c* X2 Q/ N3 x# j# m
  574. {( o/ O) i( n7 Z
  575.         unsigned long i = 0;' o* E; X3 R" [# E! l4 I& S2 x
  576.         CE_Low();                                        /* enable device */' \/ h5 N9 F( O0 c, b
  577.         Send_Byte(0x03);                         /* read command */
    ( q" O& |% b0 t: A/ c$ S
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */2 l; {* ^: W( U4 x0 r0 v5 A3 j/ A4 d! O% k
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));' |$ D% M( X' k4 J& H( B
  580.         Send_Byte(Dst & 0xFF);
    1 _, v- I" I8 c* o) Z% t3 B
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */3 s* R  s( z1 }
  582.         {
    ' `7 Y' T  @2 q3 x
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */+ Q3 W& r2 [" b3 Q/ }3 b
  584.         }" ~( i8 ?5 e, R& H7 p1 \; j  |2 ]9 j
  585.         CE_High();                                        /* disable device */# Q. n$ L" ^; y6 A4 r
  586. 7 [! W2 F8 D: {4 T& j4 G: I: Y9 |
  587. }) b# a% z3 J( P- u

  588. - T* ^0 y' `) p; v' h/ @
  589. /************************************************************************/
    ; I4 R0 \0 z  |; q1 E; x
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    0 g! _( S2 l- S+ G
  591. /*                                                                                                                                                */               
    , e$ W, t: w, q' u) O5 ^* q
  592. /* This procedure reads one address of the device.  It will return the         */! u' z+ R: j8 V
  593. /* byte read in variable byte.                                                                                        */
    - j  l6 j" j$ _8 V2 k# ~( T  Q. R
  594. /*                                                                                                                                                */
    ( L. f" Y: N2 ~' `/ g& g
  595. /*                                                                                                                                                */# }: W: _4 ]6 U$ J' s9 Q
  596. /*                                                                                                                                                */; {% l. A6 H: O8 k+ U6 ?, y' I
  597. /* Input:                                                                                                                                */
    3 }% b  m" t; {; D( [; E
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    ; C$ m, S: C. b% l' @5 z
  599. /*                                                                                                                                      */% i# G* s5 _# R4 P
  600. /*                                                                                                                                                */
    * j- T4 ~0 F, g* O
  601. /* Returns:                                                                                                                                */
    " r5 G/ j5 B% @: m! o# k+ q; G4 U
  602. /*                byte                                                                                                                        */: m; W2 m: S/ c# b: \
  603. /*                                                                                                                                                */+ ?( H+ K# h5 n5 Q6 j8 B
  604. /************************************************************************/" q7 A) t  a5 O
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    # w$ E. I: L' u! C
  606. {
    & V2 C, X5 y; i' s
  607.         unsigned char byte = 0;        8 l" C. z4 I) r9 O9 R# I, }* z
  608. , F( k* A1 z4 u/ W0 u7 M
  609.         CE_Low();                                /* enable device */
    + {3 d7 n( j; ?& O2 ]1 W: G7 g
  610.         Send_Byte(0x0B);                 /* read command */7 S+ d' {! q) Q- r, `1 b5 z- g( ~
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */- ^# D# I2 \& \$ b$ O  [
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    , g$ ]3 T1 m9 |( y
  613.         Send_Byte(Dst & 0xFF);
    5 Y3 M7 s$ z+ k4 F& m
  614.         Send_Byte(0xFF);                /*dummy byte*/5 S+ O' F& L( t" Q7 V! i
  615.         byte = Get_Byte();
    $ z) c+ W. u: E
  616.         CE_High();                                /* disable device */2 g% v- B& e& h9 F; Z3 O( e
  617.         return byte;                        /* return one byte read */
    1 n: ]; j% v. g1 A
  618. }
    & h8 L2 {* r7 O' s0 c3 {

  619. & k" B$ e! B) _4 ~0 s; c  p
  620. /************************************************************************/$ f. q, X" x  v" l
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    # W7 Z  a# A2 x. U: z8 A# P
  622. /*                                                                                                                                                */                / f  j. u  I/ b* w( I
  623. /* This procedure reads multiple addresses of the device and stores                */+ i1 v0 ?# i* e
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/$ R8 v0 t5 U& b3 f9 L4 `
  625. /*                                                                                                                                                */& f3 O5 p! c& x9 s1 G
  626. /* Input:                                                                                                                                */
    - [/ \; Y& Q- B* q9 X6 x! o" c" W4 N
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */4 j; M2 Y8 X% @9 r5 ]
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    7 m& H: g+ F+ o
  629. /*                                                                                                                                                */
    3 _' j, N  K& |6 I2 E
  630. /* Returns:                                                                                                                                */7 T) r7 t4 Y+ j) B
  631. /*                Nothing                                                                                                                        */, m# r. {- C3 U' A# C- R
  632. /*                                                                                                                                                */
    + C1 h" M" Y. b: I
  633. /************************************************************************/
    * C+ F, v6 r) }/ Q. V3 n+ O# v
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes), N& j7 h# D1 p, Q- W2 V
  635. {
    % H! x- _- [6 \( w* T' h9 k
  636.         unsigned long i = 0;
    * Q$ d$ l  e- E
  637.         CE_Low();                                        /* enable device */" [. }4 y: q2 R, J
  638.         Send_Byte(0x0B);                         /* read command */
    & i+ F! k# H7 F& i; M
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    & `0 m$ a/ ]# o' @6 z5 v5 P
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    & S' \0 N2 ^3 Z, O4 S, C0 m
  641.         Send_Byte(Dst & 0xFF);
    ' u+ I( H2 T* g% n) o
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    " @9 @: Y) j$ l" j* T7 C1 D* |& P
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */# f. O$ q# T; ]
  644.         {
    5 \6 A; |3 A: q# Q3 J
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    : m( @3 a' s1 K" j! s8 _3 e
  646.         }
    ( ]) |; T! H( b$ A
  647.         CE_High();                                /* disable device */) Z- i$ I* P( t1 O, P* J2 P* a+ G
  648. }
    2 S4 o/ ]7 N' b3 G* U) ~9 G! v/ H
  649. , j# y7 T, m( y& z8 q6 ^/ w$ d
  650. /************************************************************************/
    3 x* T7 e: u9 B/ P! N# \
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    , T  P' c; o$ o# e- E: X: i
  652. /*                                                                                                                                                */7 P# M: R# q5 S6 t$ C8 o/ q- A
  653. /* This procedure programs one address of the device.                                        */
    7 ~: Z1 _0 d. ~, y* o" b' m
  654. /* Assumption:  Address being programmed is already erased and is NOT        */, l3 B$ h8 f# G9 n
  655. /* block protected.                                                                                                                */9 j( J$ M4 z9 v3 l& M0 [. m  c
  656. /*                                                                                                                                                */
    : m3 ~8 |" W5 N/ [, b& Y9 D
  657. /*                                                                                                                                                */# W' }5 L/ Z* V) x$ A8 P) C
  658. /*                                                                                                                                                */: E: e0 J- Q' n8 Q9 r0 c% Q
  659. /* Input:                                                                                                                                */
    ! }" p, |& l% n9 n
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */( |" a2 H( g/ b" c5 e& b/ l. [
  661. /*                byte:                byte to be programmed                                                                */3 p5 C# C6 r  v2 R: e' R7 n
  662. /*                                                                                                                                      */# ~6 M9 L& g0 |5 |" ?
  663. /*                                                                                                                                                */
    7 X# \, `4 O, `' x
  664. /* Returns:                                                                                                                                */( T/ \- I" |5 F. b0 q7 F
  665. /*                Nothing                                                                                                                        */. e# z5 a( @, g0 h% @
  666. /*                                                                                                                                                */2 k+ v9 i5 O- o0 q, D0 H
  667. /************************************************************************/
    4 P9 h8 ]2 r+ M% K  S8 r
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    % D4 E1 k' s9 h7 K0 |1 x5 z, h
  669. {
    0 B) k) c* B- ?3 \! r8 e3 v3 ]
  670.         CE_Low();                                        /* enable device */, _+ a, b8 j% s  l  b* _6 G/ x' z
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    7 F6 N1 s* Q0 _- S3 @4 a
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */( l- b4 n3 {3 w' n+ o+ Z# L, D
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " |1 Z5 q8 E8 a1 H% w( c: l
  674.         Send_Byte(Dst & 0xFF);
    0 C8 f0 H7 i. _1 m: C
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    + S8 {7 |3 e8 p4 ~& K0 s
  676.         CE_High();                                        /* disable device */
    : i8 T# n" L" O& e7 H% {+ x5 K
  677. }6 U5 v# @' l) A# T5 q0 s4 q

  678. # _0 }: [! D' u, H
  679. /************************************************************************/
      G6 X/ r/ D* k) o& n4 Z- w
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */0 D! W2 m1 K% e9 L% `: K( C
  681. /*                                                                                                                                                */1 h+ F# g7 w* W/ l
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    % _% K& d; o1 d2 t2 W
  683. /* the device:  1st data byte will be programmed into the initial                 */
    $ K. g: Y7 z! b; T/ ^
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    4 @& `/ }$ V! m. ^7 y4 q
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    # C) o9 U# V+ G* I8 K. ]6 k$ p
  686. /* is used to to start the AAI process.  It should be followed by                 */# h$ |: Q$ c* L# c& Y4 R
  687. /* Auto_Add_IncB.                                                                                                                */
    3 {) m4 O$ W7 H& _2 @7 C
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    , H9 d) P+ |7 E3 t  Q! x# g
  689. /*                                block protected.                                                                                */) c1 l# j) x+ ^0 Z. w. A
  690. /*                                                                                                                                                */
    " G0 C  n- b) \, w6 j
  691. /*                                                                                                                                                */2 s+ N1 z3 j0 A8 ]$ m
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    $ b# X& [9 U1 r9 b/ o5 b. b5 Z5 w
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    # a( }. {# y$ L& T6 q6 ?
  694. /*         unless AAI is programming the last address or last address of                */! S* l* U; Z5 S  @6 _( {- a
  695. /*          unprotected block, which automatically exits AAI mode.                                */7 V* {; S: h0 W' a) |* e3 e
  696. /*                                                                                                                                                */
    . P6 v2 L9 i$ z
  697. /* Input:                                                                                                                                */' L. r& N: d- A" s  }
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */( ~+ f6 s. \7 V3 S$ g3 T4 ^
  699. /*                byte1:                1st byte to be programmed                                                        */9 h& o/ G0 I) H% P, y; d
  700. /*      byte1:                2nd byte to be programmed                                                        */
    ) h! z% C" y: ^8 e; S" `" |* F" ]
  701. /*                                                                                                                                                */; ~( q7 ~" t9 w) M1 L% `: n, l4 ~
  702. /* Returns:                                                                                                                                */( p, j* K8 }% a5 b( ~! J4 w
  703. /*                Nothing                                                                                                                        */
    - ?& `0 C( d5 ~2 F  _
  704. /*                                                                                                                                                */
    ) \3 l2 Q' W% |
  705. /************************************************************************/
    ! E  t, s6 [4 U: m, @' i
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ; ^9 _2 g0 `; J0 M  E
  707. {; x: t2 J4 E; @$ v/ A/ l/ G6 L
  708.         CE_Low();                                        /* enable device */; R7 I# {/ B4 [2 J
  709.         Send_Byte(0xAD);                        /* send AAI command */
    ! V; x. {0 N3 t: P6 \' `
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    % k$ X6 O* f6 M+ M- ]& t) u* I9 h
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    $ P6 B  w9 z' H- \! l
  712.         Send_Byte(Dst & 0xFF);! {6 \' W9 `( |3 c& E- S
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        0 F2 N; e$ w' ~/ R; B5 h2 P7 b
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */* _1 o6 ~# M( {1 C. v7 U
  715.         CE_High();                                        /* disable device *// A" M( D, I' @9 S
  716. }/ {- g  v8 h9 P2 _, T- W/ K  E
  717. 6 e$ {: }0 X  W8 ~. m. a
  718. /************************************************************************/
    + s- ~6 \" _. h) a0 y; h( B' t+ O/ G
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    ! I. ~9 s# W: w+ r: p# K: }
  720. /*                                                                                                                                                */. o1 w% d3 a2 T( S, G. o: G4 E
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*// d2 J. x" t8 ~& r, C. A
  722. /* the device:  1st data byte will be programmed into the initial                 */
    ! W3 u. r, Y" x7 E+ w# _# F! @
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    ; R$ ]* w& _) E. m
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    : {2 R$ ]' o. p1 C
  725. /* is used after Auto_Address_IncA.                                                                                */
    1 g5 P/ H; G( s, l9 W% o0 F
  726. /* Assumption:  Address being programmed is already erased and is NOT        */, M+ s" D2 c0 n" Y* `
  727. /*                                block protected.                                                                                */. `7 n4 V+ b3 |) p7 i# W& W  M
  728. /*                                                                                                                                                */2 C  H" a2 H* F( Z
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */( c" ?& _* N" [7 N% X
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    # q% _4 l& ?) P9 @* ^9 O" n
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    : A2 q/ s  u1 R" c' D
  732. /*          to exit AAI mode unless AAI is programming the last address or                */- F& Z0 g- k3 A, ^" Z) \, r+ T+ n
  733. /*         last address of unprotected block, which automatically exits                 */! `3 Q: r0 K# B2 r; S9 R
  734. /*         AAI mode.                                                                                                                        */
    ( h. ^$ m) d+ o1 R/ ?/ i
  735. /*                                                                                                                                                */" U; _5 l  H% u- P  I/ s
  736. /* Input:                                                                                                                                */: [# d2 B9 A. X' C4 V1 g" Q
  737. /*                                                                                                                                                */
    ) I- ^0 f2 F# s5 j, t
  738. /*                byte1:                1st byte to be programmed                                                        */
    # \5 s7 @7 H) F* r5 }' @" z
  739. /*                byte2:                2nd byte to be programmed                                                        */
    . J3 @3 N& J$ N" [5 I' A1 I  X$ [  O. u
  740. /*                                                                                                                                      */+ v; r, s/ E" ?1 H
  741. /*                                                                                                                                                */
    2 ]/ f; \3 V# w" ?( Y5 [  f' D, Z' R+ m
  742. /* Returns:                                                                                                                                */* Y9 K& q, K2 K, l' {0 {
  743. /*                Nothing                                                                                                                        */
    ( H, M* E! z( c0 F
  744. /*                                                                                                                                                */
    + {- G. s( Q7 Z- ~, f! k
  745. /************************************************************************/, z9 H3 G& W! W9 c1 K: l" d5 L
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)1 m5 p$ A5 H! k* r$ S, Z) D
  747. {2 p# e% D. r) o% H4 A3 j
  748.         CE_Low();                                        /* enable device */7 M, J" j* s0 ]- t% ~+ J" b
  749.         Send_Byte(0xAD);                        /* send AAI command */7 R* g( l4 U' p! P- E9 {- \3 ]8 I
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    $ \. W0 b" h: a4 b6 _3 e' U1 t
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    5 p, ?: g- M: l; e3 u% E1 _
  752.         CE_High();                                        /* disable device */  e. ^9 c1 X# Z0 q
  753. }8 \0 D* ]& T" @" T
  754. : e: g' @7 [7 n& G" v! w
  755. /************************************************************************/0 L+ o$ ?& ~& }2 U. z; _  z( o
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    ) U% B7 \8 \- }, }6 i! K; B) h. G5 Y/ q
  757. /*                                                                                                                                                */
    , u" \& A% N- {2 S5 E3 \
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */* G0 ~  M3 o! V2 ^0 |3 x
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    ; v+ `, U% \+ r0 a( M
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */9 f% |. a2 \* b, H. b) A+ A
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    / O0 C6 G4 P9 M; G0 ~0 y2 Q
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    " C$ ~8 [: p0 b) {/ [5 F& w
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */4 I7 C" A  _; x# F0 L
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */0 b$ m) W% o1 c  x& C6 x
  765. /* Assumption:  Address being programmed is already erased and is NOT        */6 t; Y4 I  V% T+ ?# E, Y$ ~
  766. /*                                block protected.                                                                                */# G# @8 N& Y' B
  767. /*                                                                                                                                                */
    ! H* W  i: B/ H0 b
  768. /*                                                                                                                                                */
    $ H! j( F2 M$ ^' x1 e* S1 v* c; J
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */& u0 N% i" h1 [! e. d
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */1 ?+ R' {3 g3 q7 [. ^
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */% n' w# T8 y; @6 B3 d7 J2 a( f
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    7 T0 j% @4 o, q: r- V# G' L8 }
  773. /*         last address of unprotected block, which automatically exits                 */0 _2 d7 }* a' j* u4 g
  774. /*         AAI mode.                                                                                                                        */
    4 l8 z3 A% N& w  {2 Y5 l- ?
  775. /*                                                                                                                                                */6 }$ f* I% o& ?( g; V
  776. /* Input:                                                                                                                                */- |/ Z$ {* m8 x, C- N( l
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */# n: X: a! K1 ?; ?* [! h
  778. /*                byte1:                1st byte to be programmed                                                        */
    - D. z: [& q- ~
  779. /*      byte1:                2nd byte to be programmed                                                        */
    6 }0 m8 E% c- P( A/ V5 G
  780. /*                                                                                                                                                */
    & Z5 w  `# a1 v/ o+ L
  781. /* Returns:                                                                                                                                */% v2 g. F6 h2 u# R& E
  782. /*                Nothing                                                                                                                        */5 L' v1 x  B) C9 G, q
  783. /*                                                                                                                                                */2 }7 }- E" i6 Y) V5 E6 H$ n
  784. /************************************************************************/
    % \  Y( D1 f! r
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    % g+ n( ~* K( p
  786. {
    * F3 c, s* q8 r9 z8 t7 A
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    ; f. ^, i# A0 G4 I! P0 k" O
  788. ; e5 T6 ^0 u1 C2 ~/ ], J" ~, ]
  789.         CE_Low();                                        /* enable device */
    5 K, E5 t) k) ^) W3 _
  790.         Send_Byte(0xAD);                        /* send AAI command */* q- x" T  f! @9 N
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    + E9 l5 K$ _9 m. g
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));% H8 ~, A! H3 @7 ^+ k1 Q6 w$ E/ P1 O
  793.         Send_Byte(Dst & 0xFF);
    2 O) W9 F2 K% X7 i3 @
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        ) f6 A- q' h* s4 `8 W6 `8 M
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    $ Y' u! O* d  R% }; ^
  796.         CE_High();                                        /* disable device */
    ) s  F! [. D' q4 R* E# X. }
  797.        
    $ M4 t' C$ {, ~0 c9 U+ n: Y1 Z
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */) y) D/ O2 V3 l; o0 M% c* O

  799. - k1 L* I- {0 k  V; a) d4 `* ^
  800. }
    * f* H; A8 I7 {  d

  801. " I# {. R- W# K
  802. /************************************************************************/
    9 L) U( ]* D, P
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    ( g4 d, X/ l" }- v6 H2 r
  804. /*                                                                                                                                                */) `, j5 I0 R8 C9 H) x
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    8 j$ K8 a) k; k5 B
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    % T1 j5 [/ n3 ?- w9 [) Z" O
  807. /* AAI programmming is completed.  It programs consecutive addresses of */+ H: k7 U5 u# g9 v
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    , I) Z6 o- k% z$ T
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    . V) |; O, D. c& r* y: r+ q' m! N
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    % \3 q& G1 S1 w. x; h* o
  811. /* used after Auto_Address_IncA.                                                                                */+ d, R/ z; p! R& \
  812. /* Assumption:  Address being programmed is already erased and is NOT        */, s3 o; {" N0 ^7 ~1 T% E
  813. /*                                block protected.                                                                                */
    " r" d! E8 m' c+ t
  814. /*                                                                                                                                                */5 ~4 U. ]/ @* B# y, n: L, }8 Y
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */8 G# n- n+ d- N  r
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    ' z8 X, b; |- `/ j0 c/ I
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    4 n9 W/ F2 _: u, i6 {
  818. /*          to exit AAI mode unless AAI is programming the last address or                */1 L3 K( n! B! \9 u0 j  {1 C
  819. /*         last address of unprotected block, which automatically exits                 */: |5 l; M3 }) U/ F) E
  820. /*         AAI mode.                                                                                                                        */
    $ @1 f/ I& y* O' z& O1 w& b: ^
  821. /*                                                                                                                                                */
    . I1 g( A# y7 i( _8 {" J
  822. /* Input:                                                                                                                                */
    ) x& p! [6 ]9 |
  823. /*                                                                                                                                                */
    / k" s2 L" m7 _
  824. /*                byte1:                1st byte to be programmed                                                        */
    . B, }* S- J$ x7 }1 _7 m$ Y
  825. /*                byte2:                2nd byte to be programmed                                                        */0 E4 t: V# I. Q: R" j! k4 d; P* M
  826. /*                                                                                                                                      */4 F- ?( A- c3 m
  827. /*                                                                                                                                                */
    8 {$ S% q0 X! |. V4 K( A* H
  828. /* Returns:                                                                                                                                */
    8 a8 X7 ^' v/ @4 ?3 d4 x) z* k9 z8 T
  829. /*                Nothing                                                                                                                        */
    3 |/ C: S( q; v, \& d# y! G
  830. /*                                                                                                                                                */& S# O# X2 k. S5 C
  831. /************************************************************************/* \7 n1 J+ l, V0 \$ r3 ~' b% V
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2), e, ^* n- s) O" h9 d  F1 [3 ~" I
  833. {
    + t$ E( m2 ~$ g0 s6 }
  834.         CE_Low();                                /* enable device */6 T* Z* m6 U6 N1 ~" ^. Y+ `
  835.         Send_Byte(0xAD);                /* send AAI command */
    ( {- B5 S- a# @4 O, M
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    * L, L( F* l& V6 I4 ^2 `$ |( L
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    3 }# s: m6 j- k: K) t4 }7 g
  838.         CE_High();                                /* disable device */
    + r0 t/ |$ X$ n* i% L( k
  839. $ H6 B0 d5 O5 j8 _
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    * J5 ?% ^1 Z, A( a- }' T+ p, q6 H# C) F0 a

  841. 6 j% R4 R1 r$ \; o! j1 ^
  842.         WRDI();                                 /* Exit AAI before executing DBSY */1 Z9 `+ j3 ?9 H5 s/ z% P# ^; V0 G
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    + b8 l8 Z8 V6 Q; W9 }9 e
  844. }
    ' X/ i8 ]* W, N

  845. # y0 ]: ^$ I9 ^- n
  846. /************************************************************************/
    $ p* j  q% I* o5 R& j
  847. /* PROCEDURE: Chip_Erase                                                                                                */. R# V- Z3 C! p/ O( J8 A3 C( B7 P
  848. /*                                                                                                                                                */
    & R- I/ a3 E  {2 M8 ?- ^! y
  849. /* This procedure erases the entire Chip.                                                                */
    ' X7 K8 y. F2 O+ n
  850. /*                                                                                                                                                */
    % f3 |, b9 S% _: _) H
  851. /* Input:                                                                                                                                */
    0 g; {, R3 _) C; q0 I$ d& T  x" n
  852. /*                None                                                                                                                        */
    8 b& \) j3 p/ j! Q3 G" [
  853. /*                                                                                                                                                */5 L; |5 a3 g  z
  854. /* Returns:                                                                                                                                */) O& E( K8 [2 b9 H& N
  855. /*                Nothing                                                                                                                        */$ ]( t7 F2 d9 L& B* |! a8 K! z7 |
  856. /************************************************************************/
    6 H( c% A" E& C% L! i3 J- Z
  857. void Chip_Erase()
    $ E* t+ V& P, ]  h- F  o' E
  858. {                                               
    , O3 D% L( j* s- {1 d2 P. y
  859.         CE_Low();                                /* enable device */
    8 ?6 a/ H# Y' @
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    0 t6 R1 R1 ~- g# U7 y3 K- i% |
  861.         CE_High();                                /* disable device */
    $ ?+ J1 ^$ R/ G( x, I8 G4 s. x
  862. }4 G9 [& Y. s! v8 C+ ^
  863. 6 q2 K9 d- k5 N& W1 c1 {
  864. /************************************************************************/
    5 M( ]! f1 f- ^+ ?
  865. /* PROCEDURE: Sector_Erase                                                                                                */# `* y3 {  m$ x, I
  866. /*                                                                                                                                                */
    6 q" O4 ~. ^6 W* j0 r6 |- H, [/ ]
  867. /* This procedure Sector Erases the Chip.                                                                */% c7 H" A: W& T5 s
  868. /*                                                                                                                                                */
    0 C( M2 I# `; _" K7 A8 I
  869. /* Input:                                                                                                                                */# ^, H- h: B6 ?" l" z# |
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */; A) o2 {1 h3 B$ Z/ R$ R" O
  871. /*                                                                                                                                                */
    . A/ |5 ~' S" s# x
  872. /* Returns:                                                                                                                                */& y0 C8 }4 ~- m) ^2 w( b  b
  873. /*                Nothing                                                                                                                        */
    / a7 `  T! ~) o# ^; R, f
  874. /************************************************************************/
    5 e5 T7 X. G: P) j
  875. void Sector_Erase(unsigned long Dst); `( n& k. ]4 N/ @# Z8 ~8 j
  876. {" t( c. T0 M9 q$ r

  877. 4 C1 T) G4 D4 m8 f

  878. 3 E0 D, @7 r6 M( v" @0 _
  879.         CE_Low();                                        /* enable device */! P5 z5 D# ~. w; ]: B+ A+ ]: P5 [; p
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    0 n2 L9 M' }4 u5 s; I9 G$ x
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */$ ^1 B9 e( Z# }
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    3 M! f+ ^1 M+ e# p: u
  883.         Send_Byte(Dst & 0xFF);) u4 S! n) ]! P8 g4 S$ T( \
  884.         CE_High();                                        /* disable device */
    ! F, {, d: s5 n7 M1 i+ T8 L
  885. }        # i$ A: V$ o) t- [$ |7 Y- \; |4 v
  886. + G' B3 M( g+ C% {  K, Y2 q
  887. /************************************************************************/! [: e0 N/ q/ D3 }
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */7 q" `8 {- |, Y- k4 ~+ d
  889. /*                                                                                                                                                */  n. d+ V/ t" h6 A: J( m& F9 b
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */* [; I" g+ o" @% A
  891. /*                                                                                                                                                */( o) W- d% H1 [& q4 x6 [5 {- }
  892. /* Input:                                                                                                                                */& y1 Z; _, }+ Y/ K- ^
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    4 I- ~' v1 z" A- r
  894. /*                                                                                                                                                */- U5 l# K% K. D. _  [5 s5 O
  895. /* Returns:                                                                                                                                */
    * a2 }8 ?4 _  v' R3 G
  896. /*                Nothing                                                                                                                        */
    4 j, i$ |9 o& M& i1 r
  897. /************************************************************************/
    5 j; L& p( C; X) [
  898. void Block_Erase_32K(unsigned long Dst)$ X' C" W: I$ @! }
  899. {- m5 U9 @2 L* ^5 x8 W2 \
  900.         CE_Low();                                        /* enable device */
    , }: P* V: h& A/ W/ l* Y
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */. V0 V# X' C- ~6 e, m' y
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */. {% P8 P+ l8 w# o1 p4 y4 v
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    + K7 j5 i( `* b" f: D" N$ e
  904.         Send_Byte(Dst & 0xFF);. o6 ~/ p% h; C( ~4 D/ p# |6 L  U
  905.         CE_High();                                        /* disable device */
    5 W: }) ~- d6 M: [* n6 p+ K
  906. }
    9 N" G% y. }, ~! p2 q2 Z

  907. & A, G6 R3 {! L
  908. /************************************************************************/: A+ `3 {! v" @
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */' D' I, U7 U$ g
  910. /*                                                                                                                                                */
    + {8 y6 ^1 V' J
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    - C7 J- x% r4 X6 m5 K
  912. /*                                                                                                                                                */
    4 Y! V3 x- a  K
  913. /* Input:                                                                                                                                */
    # k; J" Z# ?( q$ i
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : }: y$ @3 d: r" x7 q9 }% H
  915. /*                                                                                                                                                */
    ( Y7 ]( Z, u  }* m: N! M6 C7 \
  916. /* Returns:                                                                                                                                */+ G2 V1 U" f  l0 E1 B: M
  917. /*                Nothing                                                                                                                        */: z5 @& i7 @' U  D1 U, l
  918. /************************************************************************/
    0 U' A, n8 ?2 N( \: }+ q' A
  919. void Block_Erase_64K(unsigned long Dst)
    ! ?: v( D4 u5 j0 I$ Y
  920. {
    $ z0 O( N6 a% S8 U. d9 d
  921.         CE_Low();                                        /* enable device */
    ! [) I5 X( j# v! O
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    $ F0 n1 ^- L/ i  r
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */6 ~, K' O" ^: Y: Z* d8 O' T8 X/ H2 t
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));6 U9 W' l, W/ _
  925.         Send_Byte(Dst & 0xFF);
    / P5 l1 ^% _. f7 o& U- L3 X
  926.         CE_High();                                        /* disable device */
    " O/ d; _* S* U! _& ~. `
  927. }
    % @+ o" H% o& e: m( \1 F& {

  928. ! X5 D7 G& H6 P; A. R7 X& ^! ]
  929. /************************************************************************/' @$ V' z( d$ m6 F$ W
  930. /* PROCEDURE: Wait_Busy                                                                                                        */5 E9 w# j" P: a! G
  931. /*                                                                                                                                                */
    4 h2 b( v$ Z' C: ]
  932. /* This procedure waits until device is no longer busy (can be used by        */
    ' \" o) v1 Q4 [$ o, ^
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    7 l' z7 j: u/ x5 }
  934. /*                                                                                                                                                */6 y( @! O; \6 @4 I; Y
  935. /* Input:                                                                                                                                */
    6 g, t1 X2 F9 w5 I6 L
  936. /*                None                                                                                                                        */3 _5 n4 g. }1 l
  937. /*                                                                                                                                                */
    + V( Y7 d( |; L' V
  938. /* Returns:                                                                                                                                */
    7 u7 {, d4 C$ w( v$ k/ x0 ^
  939. /*                Nothing                                                                                                                        */
    * F0 @* c, k# S, u
  940. /************************************************************************/
    & k6 Y  m- \" \7 s* t9 H
  941. void Wait_Busy()
    ! e7 I: N, N- E0 P- T2 E9 F
  942. {1 E0 R. U+ W0 o6 \, ~
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    % w8 P6 `  f+ P5 o1 q. a
  944.                 Read_Status_Register();
    # P5 ]2 V! V# b3 B" r# H7 p, S6 U6 O
  945. }
    9 `, I8 i1 R* E5 S1 U8 R3 i. V

  946. 0 |) M5 s; r0 k' W* b, g' t9 [
  947. /************************************************************************/  u2 k7 v* B$ \2 E
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    * R# T3 ?) c8 f( ]/ S
  949. /*                                                                                                                                                */
    % @: |  t2 W$ J, S; O; H! S
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    8 _  s. l, _; g9 K2 F0 Z
  951. /*                                                                                                                                                */
    2 z+ r0 W4 [8 q. G3 X! Y; D
  952. /* Input:                                                                                                                                *// j) G# m% M5 O( g. h0 j6 [
  953. /*                None                                                                                                                        */* ]9 q  m( M1 D
  954. /*                                                                                                                                                */1 c: c% e, v  P
  955. /* Returns:                                                                                                                                */3 u4 }7 e- v4 [9 ?8 w' q) Q
  956. /*                Nothing                                                                                                                        */
    ) e5 R2 Z& e. s3 Y' R
  957. /************************************************************************/# x8 B- f+ b$ M  A# R! e. j9 ]* E
  958. void Wait_Busy_AAI()
    . |- c5 E& @  x' G1 J( v7 o
  959. {1 q( A  A: b; ?" H7 ]6 w- _
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */0 E1 {- ?+ r9 u
  961.                 Read_Status_Register();: E& U3 {/ Z+ w
  962. }
    5 [, n/ G( _7 Z
  963. 0 s! E4 b0 q- \0 n3 P0 S; b3 h* G, o
  964. /************************************************************************/
    : x) J' X0 n4 J' {- Z
  965. /* PROCEDURE: WREN_Check                                                                                                */& ?( _/ \# H4 |" s
  966. /*                                                                                                                                                */# y, l7 A! F) j) o$ J
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    & {  G. X1 m& N9 U0 Z+ A9 H
  968. /*                                                                                                                                                */
    : _% K+ V- I( M" S
  969. /* Input:                                                                                                                                */
    ) T" v5 A( M+ W4 Q  w5 |( `( W
  970. /*                None                                                                                                                        */
    & d" ]9 M% K+ g1 J5 ^4 o9 d8 [
  971. /*                                                                                                                                                */
    ' c" m+ b% m7 ~) V" ?6 \% u
  972. /* Returns:                                                                                                                                */3 P( A9 Q1 f: g1 Y4 k6 C
  973. /*                Nothing                                                                                                                        */
    % B$ k, O# h1 {3 f# U. k: a
  974. /************************************************************************/
    4 ^& `) [$ K5 J) I3 ?$ ~/ U% J
  975. void WREN_Check()
    % }6 k2 n& C1 a  d3 a
  976. {
    3 w! l: C& i- ~* Q0 x$ }
  977.         unsigned char byte;! D# B1 B6 y  w' z; j7 n
  978.         byte = Read_Status_Register();        /* read the status register */
    2 `/ I( ]  j  S, c& c) y7 O
  979.         if (byte != 0x02)                /* verify that WEL bit is set */5 ]' X- }$ N6 A! V' r  v
  980.         {
    : L6 l  Z% T4 y
  981.                 while(1)9 S6 h# \, R8 ~* t9 N' a
  982.                         /* add source code or statements for this file */$ v5 R  j+ O8 C4 p4 C
  983.                         /* to compile                                  */8 }9 [8 _5 k  T! C
  984.                         /* i.e. option: insert a display to view error on LED? */5 g5 [0 l" |% q% i% i
  985.                  # T& P  r8 s: C) `: c. R+ n
  986.         }
    ) Z" @% n$ i/ _  x) F$ Y0 U
  987. }
    " O) q3 K! S6 x
  988. / c- {: l$ w- M- K+ i7 P, C
  989. /************************************************************************/
    % v+ b  m6 d  w* d0 s2 ]
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */+ S. u* T4 W- s9 g( U" d
  991. /*                                                                                                                                                */
    : h+ c6 v, x4 B( h$ ?0 a
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */. e$ T0 X* y2 M! Y, h7 C6 b  \
  993. /*                                                                                                                                                */: u- R% P- Y5 e4 |/ r, Z1 ^& a  B
  994. /* Input:                                                                                                                                */- P8 Q. [# j  g0 N: {) {" k
  995. /*                None                                                                                                                        */+ |  c/ @7 m" e- n7 D7 T( n1 v
  996. /*                                                                                                                                                */
    ! R$ q3 O1 L1 ~" i  A
  997. /* Returns:                                                                                                                                */
    * s9 e# M6 l6 c9 y" A6 W
  998. /*                Nothing                                                                                                                        */. T2 o9 R6 q3 a. p' J
  999. /************************************************************************/$ q) H' O8 ~+ r' K
  1000. void WREN_AAI_Check()
    ) a; t2 O9 w0 p  ]. @5 S
  1001. {, m* E% Q* Q0 H
  1002.         unsigned char byte;
    " M2 C4 Y. ^  y: ?% l1 ~4 @. z' H
  1003.         byte = Read_Status_Register();        /* read the status register */
    1 Z+ K* n- ~% @6 ]0 w
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    : T1 M1 o* P. S# V7 c7 e! s3 ^6 A
  1005.         {
    " T5 j4 C4 h& g  e" M
  1006.                 while(1)               
    * {. F+ N/ ~/ F9 L3 c: }% X: {
  1007.                         /* add source code or statements for this file */
    & H1 P8 h5 u  ^2 C
  1008.                         /* to compile                                  */
    $ ]6 v) k, U4 E
  1009.                         /* i.e. option: insert a display to view error on LED? */
    * f% e) i3 w* ^9 x
  1010. ' X1 s+ c$ R# R9 l$ ^
  1011.         }- o$ w8 J& N/ X( v
  1012. }
    5 m; ]6 i, E. V  `

  1013. : `  m! i9 \2 X8 d) z, N
  1014. /************************************************************************/
    8 H1 u. @5 {7 E# }
  1015. /* PROCEDURE: Verify                                                                                                        */
    8 Q* H8 C+ [" k6 s
  1016. /*                                                                                                                                                */; M0 u! d5 a% V' Q3 S
  1017. /* This procedure checks to see if the correct byte has be read.                */
    . q/ ~6 ~3 k# E$ ^! Q
  1018. /*                                                                                                                                                */0 i$ t. P- z9 O, d/ X. P0 X9 v9 a
  1019. /* Input:                                                                                                                                */$ M; |1 P) B& f
  1020. /*                byte:                byte read                                                                                        */
    ( W0 [8 F+ r& u) j( l, c% K2 k7 q% h
  1021. /*                cor_byte:        correct_byte that should be read                                        *// Z% d$ U1 Q' L! o
  1022. /*                                                                                                                                                */
    / i$ x  X; Y& Q2 i* N' T5 \
  1023. /* Returns:                                                                                                                                */. M7 w( h' ~8 }' O. ]* ~$ n2 I
  1024. /*                Nothing                                                                                                                        */; T' b3 F$ n. T0 n2 ^
  1025. /************************************************************************/8 B! i/ Q1 `, @( a5 M% C& L
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    ) C2 p' H( W# K' [6 I
  1027. {
    0 w2 V3 X2 V5 ~/ H6 t- i
  1028.         if (byte != cor_byte)0 E: _- v, E+ s; G$ e$ J
  1029.         {( {" U9 R( b; D0 C
  1030.                 while(1)
    % z' v- ]/ i7 [% P$ `8 r5 O
  1031.                         /* add source code or statement for this file */
    5 ~4 [2 T4 a) w3 Y" w$ a7 n) E
  1032.                         /* to compile                                  */
    : T' B# C5 @; ]
  1033.                         /* i.e. option: insert a display to view error on LED? */; O7 }# i- c' K$ Q
  1034.                 2 }0 p; i7 r1 ?/ D7 K
  1035.         }
    " _  y  L: l" h
  1036. }
    - G% Y) V* e. n2 [2 @

  1037. " D+ P- D0 H2 c* e' ?* f
  1038. 5 z0 _: {9 I0 f8 \9 m- {
  1039. int main()
    ) h2 E* |+ A9 [2 p0 S2 }+ A% W- h( U
  1040. {, T7 o1 V1 w4 N) s3 x- n+ A
  1041. ! u- {+ `0 E4 w7 P
  1042. return 0;
    " N; r( J/ }/ v; R0 h* b, Z  P/ ~+ q
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:" {/ _* _) P, F7 M# m- Y
   main()" \5 U. ^% J. _
   里面怎么是空的呢?$ ]7 x' d4 Z: w. K& u" i8 }
   发一份给我吧
! R) D& _9 t8 [1 P7 S: ?( Tmail:luyijun2005@hotmail.com$ ~7 L- K4 A& G% W' q
咯。。。。
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。
5 Z4 d* K3 d( i1 t4 B8 I8 n9 i3 d& r" f# e6 a4 h8 r3 x
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。! F* h8 }4 |" C5 |# Z4 |
EC的代码在哪跑,你看DS的说明,每个EC都不同的。
0 t" U* r7 A" p& l$ V  B( \OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?" T" p. m* J9 B
上面几个问题是你没看任何东西而白问。
/ L# I; P3 _7 n; ~( [
  `$ @5 i2 U* z6 Y至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
9 A2 ~5 _* O+ ]& b5 w
! m6 [, N0 }  J关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!5 H5 G- c4 `8 h, o/ R* v8 S5 K

4 Y' P1 ~, t9 e: o2 {: K) d) b7 j关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”- W* _  J8 \8 L* z( {

- o! T1 ~- v6 M$ y. ]( e$ I关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...9 q3 z# K$ K2 H' I  y
* B2 {* s! d  D, `8 v. e1 s
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样7 ?( G, m$ G# o( C" F
似乎要把SPI能support 到最大,这EC chip应该有好卖点
; n  V# Q5 ]! y: P. gBIOS功能要不要强大,也就决定了SPI Flach的大小
1 d7 {% [4 ]- m+ \2 k/ {3 P2 `* |我是这么想的~让OEM去决定要挂多大!
, W" t2 t" \/ U4 w) b! R+ k如果我司有BIOS工程师就好了~哈+ ]1 L$ J" g  D. I! E  s- P
WPCE775应该算很新的东西,来看它支持到多大?& K6 n. {" u& b
: h1 i( U9 v) J3 C9 p0 m
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
- G$ y) R$ Y: t, I3 {其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
7 s0 v, K% @  f" S: x
! l+ Q( n1 j9 Z( {  B) t4 X这份driver收下~希望以后有用到( E; y. z0 F: q5 c! E3 m% c
谢谢bini大大
/ V) \7 ~- S. O2 u! O+ o
0 l( V' @8 p: Z3 B* T; k很新很新的新手,如有错误请指正 (准备看第二家的EC SPEC)
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

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

这个函数看不懂Poll_SO()

void Poll_SO()  ~3 h% O" \8 v  J# \; B9 a7 s+ l# x
{
' o4 V" a$ ^# s6 E& W$ g5 s        unsigned char temp = 0;
# ]- y( g8 l& e, L5 L( z1 V        CE_Low();
2 n4 o+ M- S2 w1 @7 e    while (temp == 0x00)        /* waste time until not busy */6 L' Q' i( ]8 n" ?  J& s: N) F
                temp = SO;9 F! j+ h, ^" m1 I& {
        CE_High();$ x0 Q! M) L0 ]0 O* p/ W) Z
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)! E- H8 x$ E  x
{
/ I2 [2 ]- G- O: f* l% G+ d' A        
4 ?. D# K- q6 {) q- G8 R- ~" |        unsigned char i = 0;: e7 V5 Y% J3 ^4 A7 B$ v( \& d, i
        for (i = 0; i < 8; i++)( E6 g, ]+ p# U1 j. A: L
        {
$ q! ~, x& W+ S6 j1 r: q                2 h+ Q2 k2 ~2 }) M" k' F
                if ((out & 0x80) == 0x80)        /* check if MSB is high */8 E: a1 k+ q- j! P- p
                        SI = 1;4 A& ?6 @; g$ a9 l" s4 K( ]
                else) T. f' p- z& r, _8 y8 L( b+ W
                        SI = 0;                                /* if not, set to low */4 D, t$ o0 ~2 X. ?
问              SCK = 1;                                /* toggle clock high */- |' G# {+ g5 F- X9 o( e6 t- ]7 E. A. Y9 Z
   题            out = (out << 1);                /* shift 1 place for next bit */' i' ~5 h) e% D* ?1 m
                SCK = 0;                                /* toggle clock low */' j4 o' p# o% O
        }! ?' g7 n5 Z: g1 U
}
& P$ |3 R9 ^6 Y; b9 R2 x; l 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-2-21 09:44 , Processed in 1.529755 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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