找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55157|回复: 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, I4 w: v/ ?0 j$ O! j2 F
  2. 4 u* D# D$ z) q. i0 }$ a
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    1 e$ Z. c% }0 X

  4. . t7 L: z/ N# k" G) t' T
  5. November 4th, 2005, Rev. 1.0
    0 \" C: M/ W) k$ d  G

  6. 1 x% O0 |9 `5 s6 O. W
  7. ABOUT THE SOFTWARE
    * U0 o3 V1 j+ c0 h0 S' R: D' i7 P
  8. This application note provides software driver examples for SST25VF080B,
    9 I* {- P6 ^0 x, H5 M) l
  9. Serial Flash. Extensive comments are included in each routine to describe
    ( N) t- h2 o4 k3 D. b! [) r
  10. the function of each routine.  The interface coding uses polling method
    " ?. [" p; Y6 U6 Q) K
  11. rather than the SPI protocol to interface with these serial devices.  The' c- F& m1 c+ a( h, B& ^
  12. functions are differentiated below in terms of the communication protocols
    : o" V3 {" ]5 S9 e
  13. (uses Mode 0) and specific device operation instructions. This code has been
    ; y8 O6 `2 m% v6 q5 t
  14. designed to compile using the Keil compiler.
    % p# \, I, w) l  u* l4 f) h

  15. # c! _4 {  f) T; |. @9 D2 X2 z

  16. 8 K/ U, u4 S" ~0 B; h6 y7 U
  17. ABOUT THE SST25VF080B8 N' k0 g) a7 i4 \

  18. ' ^9 M) h! q3 p! _9 X/ @7 j8 ~7 k
  19. Companion product datasheets for the SST25VF080B should be reviewed in / r, i8 ]' }% X, z  H
  20. conjunction with this application note for a complete understanding
    & @- J# C) }% t% q
  21. of the device.; |% R+ `  \7 q

  22. ! m, U, b4 \0 ]# I6 \
  23. : B$ W) c% S0 R. H- O  W* k
  24. Device Communication Protocol(pinout related) functions:
    9 x* P" x2 ?% l) `
  25. 8 v" Y, H8 j, [* T/ N
  26. Functions                                    Function
    , D; I. _/ B  j) G8 d; d: X2 I* Z
  27. ------------------------------------------------------------------
    0 N* l- ~( k- p3 F
  28. init                                        Initializes clock to set up mode 0.- U5 C% ]$ p, H4 T
  29. Send_Byte                                Sends one byte using SI pin to send and ' B8 w# D  `. u2 s2 }* @; |
  30.                                                 shift out 1-bit per clock rising edge
    $ b, e# n" K1 p8 Q( P8 |1 \- P
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    , G- P0 ~# N2 k+ Q% @( N- T
  32.                                                 in 1-bit per clock falling edge9 Y2 A1 |. L: ^# e+ w
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming7 H/ }8 n! m: `1 D( X2 Z* q( e
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high- R' }3 C: C: _+ ?6 \
  35. CE_Low                                        Clears Chip Enable of the serial flash to low5 a! `# N3 n, H: h5 s
  36. Hold_Low                                Clears Hold pin to make serial flash hold8 _( q) h; n. Y4 z) O8 i
  37. Unhold                                        Unholds the serial flash
    + _9 g7 p4 m+ b  u/ r2 E
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    ' ]5 \' G/ u8 w
  39. UnWP                                        Disables write protection pin% y4 P6 K8 y! t; g3 t9 b" ]# S
  40. 7 H. W3 s& c$ Q' M9 }8 q- L
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    7 P8 N6 G; D% l3 V/ B7 h
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
      N0 b! D/ S/ H7 ^* j2 \6 B* S
  43. software which should reflect your hardware interfaced.          
    ) [* T7 i6 `. S5 d, g) x

  44. 9 L1 D5 [7 E# |  a; c
  45. / C+ I8 A6 o# N  _. L$ ]- O9 I
  46. Device Operation Instruction functions:
    5 N8 \4 V5 b' \% b( x7 t
  47. 1 t* l0 f7 o2 k/ D" x7 ~
  48. Functions                                    Function5 D  [. ~7 J$ ^- e0 o3 m  x
  49. ------------------------------------------------------------------: c0 g+ L. l# O$ _
  50. Read_Status_Register        Reads the status register of the serial flash
    9 Q! B6 N5 c) }* v4 N7 L
  51. EWSR                                        Enables the Write Status Register
    , i' N/ }% M# G7 n7 @* J
  52. WRSR                                        Performs a write to the status register
    # \' N" Y' x+ [' K9 v
  53. WREN                                        Write enables the serial flash8 G( P2 Y, T% W; K2 s+ P
  54. WRDI                                        Write disables the serial flash6 W9 T5 v2 o( A' `# }" l
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    ! C: f0 X) n. {* _% |
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming* l, z6 K$ V" `4 k
  57. Read_ID                                        Reads the manufacturer ID and device ID
    7 R# j2 i' j/ h
  58. Jedec_ID_Read                        Reads the Jedec ID
    ! A. C1 v% N7 g4 H6 D
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)5 M1 K( ?5 Y1 ?3 x5 i
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)! b; s# ^0 W1 h, J3 \+ D9 o! ~
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    $ K  G3 t5 G9 }# l
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency). s, H* f/ d# d2 b8 I: ?" a3 i  c9 Z
  63. Byte_Program                        Program one byte to the serial flash, g# F" W6 c; Y8 ^) L3 Y
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    " J' X3 t8 ~' c8 A; |
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation% ]: ~: Y* @( R$ w& C/ H: D  c% G# X
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    ) ]% h: n! [( v% ~( g  }8 U
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY$ o0 h! ?' t& e; v
  68. Chip_Erase                                Erases entire serial flash
    " P3 [% R* r3 s+ j7 T' w
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash  J, M4 e, B( p
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    2 B7 u6 g) t# ]' W% ]2 m( z% Z
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash1 [( Z$ w" s' Y) M
  72. Wait_Busy                                Polls status register until busy bit is low- q) I, U/ r6 g' c( _6 B
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    + `# r2 O" ~! U7 _: R' I9 H
  74. WREN_Check                                Checks to see if WEL is set
    % M1 V6 D1 G& w4 P
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    3 c2 h( R9 p" o1 r6 I3 m
  76. + @  ?; I$ d, d  t- }; d
  77. ' U5 |* h# N, h( H" l6 `# G* \7 J

  78. 9 \& H% ^% z5 l/ B$ K. d1 H
  79.                                                                      . s2 P" @2 S5 ?/ ~! h
  80. "C" LANGUAGE DRIVERS
    3 S6 F* x2 T  Q" j( k; V
  81. 7 g& c. _1 `" w
  82. /********************************************************************/
    ! _' m- D' l2 p$ D
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */* e$ @- M3 k& u/ Z- M9 U7 I" ?
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    ' h$ ]& S& a4 J* P! L1 H
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */' E& l0 r% Z* \- R/ l
  86. /*                                                                  */0 M9 Y2 P3 {+ c. E3 P- g. k
  87. /* Revision 1.0, November 4th, 2005                                                                          */   4 v+ w5 y6 _& w1 ]& d' n( ]7 G
  88. /*                                                                  */# B3 a% S. G6 k. \& F$ n
  89. /*                                                                                                                                        */
    # R- e( J  c7 S! ^0 J  J2 C' ~- w' e
  90. /********************************************************************/- q8 a9 ?( `! a
  91. # I# J6 [+ n, g4 i  H
  92. #include <stdio.h>
    - E$ P  m7 w' ~) O0 E( g
  93. #include <stdlib.h>
    & P4 E# j% I' O; ]% Z
  94. 8 ~9 j- j4 a! {
  95. /* Function Prototypes */' g, R9 G2 v, w  L% t
  96. ) T& H+ B3 B. ~' O
  97. void init();
    4 j  d% q& U! y' ]2 E$ g5 m) \7 G
  98. void Send_Byte(unsigned char out);
    6 H% R' `4 o' p/ P
  99. unsigned char Get_Byte();) n% W2 d/ \. J' V
  100. void Poll_SO();# d+ L$ W+ T/ M* q! W6 t
  101. void CE_High();
    7 w- I2 N1 G# S5 q( P. W
  102. void CE_Low();
    2 c5 r- W# N$ s
  103. void Hold_Low();; m1 R& E+ w7 V# ]8 d2 c
  104. void Unhold();; ]2 g  ^5 l6 E6 U) H- H, V
  105. void WP_Low();: L2 G, {5 C6 L/ U! K4 o! g) e
  106. void UnWP();
    % D$ ?; D5 Z1 P3 I' `3 j" ^  ^
  107. unsigned char Read_Status_Register();
    " U# H" C* F/ w3 N! u
  108. void EWSR();
    + f- r& P+ I& H& g: F  F" @
  109. void WRSR(byte);
    8 R6 Z: W7 m- i7 w! }# N" c  j  f
  110. void WREN();
    - }3 a4 |- J+ ^# F1 z
  111. void WRDI();- E: A% Y2 K% z9 _* I
  112. void EBSY();
    7 B- q. D! `8 P1 I2 W( {, N
  113. void DBSY();1 K- k- N4 B! O' r) ]; T
  114. unsigned char Read_ID(ID_addr);
    - ~; G) Z1 b' d* W' `
  115. unsigned long Jedec_ID_Read(); ' M+ Z+ V% M) c: |$ f
  116. unsigned char Read(unsigned long Dst);+ h6 f7 M$ i7 [/ a# ]
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    & b* F& d) Z- }' F
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    / c1 P/ h3 k  G7 ~8 U# C
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    1 _+ `; g$ P, o* v( j% M! [
  120. void Byte_Program(unsigned long Dst, unsigned char byte);3 [" w$ @" b7 l  c
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);, N; t4 ^% y' C7 |- F5 Y$ j, x
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    : U; G/ h( G# e
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    6 `, f. D: }: ~0 a  s5 }  W8 f2 r
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);% K* V1 v- n( C* Q) U
  125. void Chip_Erase();. [: S' B( s- z. d8 Z
  126. void Sector_Erase(unsigned long Dst);
    1 L! m& b9 N# R# ]( K+ j0 @  o2 F
  127. void Block_Erase_32K(unsigned long Dst);( d% u3 m( f; r& n( Y
  128. void Block_Erase_64K(unsigned long Dst);, D- e4 x  b4 @' q: b* E6 G
  129. void Wait_Busy();
    0 T  `9 ~* v7 }  O
  130. void Wait_Busy_AAI();
    ( C1 I* I9 `* Z% `
  131. void WREN_Check();( F# ?9 M' F1 {) L: o: I7 _; g: Z
  132. void WREN_AAI_Check();/ C8 ^- v$ ]5 |* f, |  v* f

  133. 1 N- P4 u- E( g+ q( M* D7 i
  134. void Verify(unsigned char byte, unsigned char cor_byte);
      m9 X1 d5 J4 f' `+ y; ~8 H
  135. " X& R) W+ p: i( O7 M; B$ w1 o
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    ( j. {1 [& @. q4 V5 Y9 R- [
  137.                                                                                 /* to upper RAM area from 80H - FFH */" x: n4 _" {! }. |2 K* \5 c
  138. 3 u$ m& g" ?) W' G
  139. /************************************************************************/
    % {4 m( p4 B  P# X
  140. /* PROCEDURE: init                                                                                                                */' N: y. y; {0 Q0 o, V
  141. /*                                                                                                                                                */
    % f) Y0 q3 {3 J! P9 N% u" }" L
  142. /* This procedure initializes the SCK to low. Must be called prior to         */8 G+ O( m8 I* o& [8 x; k
  143. /* setting up mode 0.                                                                                                        */
      Q1 A9 Y  ^) J6 U( G* y
  144. /*                                                                                                                                                */
    . r) e6 o; Z2 U2 g" \
  145. /* Input:                                                                                                                                */
    ' y- e; I) Z9 u, q. ]  c5 _: p
  146. /*                None                                                                                                                        */6 w9 }2 i+ ?4 `5 W% Q
  147. /*                                                                                                                                                */9 C# R$ r* C* }% B: v
  148. /* Output:                                                                                                                                */1 w2 a2 Q4 w! }# I8 t
  149. /*                SCK                                                                                                                                */
    : d$ t3 T0 K/ }/ E" [
  150. /************************************************************************/! T, C: \  P$ a7 _
  151. void init()- n8 E4 @: [. O0 @5 ]; b
  152. {6 l! l, M& R! O5 ]" M7 ^. E0 G
  153.         SCK = 0;        /* set clock to low initial state */% T( i0 }6 y" r" F$ N2 H* z' S
  154. }
    1 f) e. |, F4 A$ k: n$ t

  155. ) R* w5 P' o! W% N
  156. /************************************************************************/- x, S+ L( S# g/ O' R
  157. /* PROCEDURE: Send_Byte                                                                                                        */! J% ?$ C8 U* M9 x
  158. /*                                                                                                                                                */) V1 v$ H& g. u: V* f& `/ v5 `$ B2 Z
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */: h2 h1 Y# _1 H' a
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    . h) l3 |0 a4 h9 D2 ^) X) W
  161. /*                                                                                                                                                */
    : @, ~9 o+ y$ F, n/ Q
  162. /* Input:                                                                                                                                */8 B, m! h$ \% ?4 Q  R, O
  163. /*                out                                                                                                                                */. S* S# E! r6 y$ |1 h& d( ^
  164. /*                                                                                                                                                */3 C0 r5 S1 `) H9 p; U
  165. /* Output:                                                                                                                                */  i0 y" F* G! |' L$ z, D* q9 v4 u
  166. /*                SI                                                                                                                                */2 ^& a0 E) o1 r, e) ~) _9 J, ?1 ^
  167. /************************************************************************/
    2 V& D' S+ s2 R( j4 E% F0 d
  168. void Send_Byte(unsigned char out)
    * l+ H- f3 `  H' U  N
  169. {4 P  N* @. @- U1 j. c+ g7 u
  170.        
    ( y! x( Z4 t# e( ]: Y
  171.         unsigned char i = 0;
    : e" W! V% H% [
  172.         for (i = 0; i < 8; i++)& {4 _  c+ Z: e# W
  173.         {
    " G5 y  k7 S* {
  174.                 0 D2 q- [0 ?+ N: z% B) s" z
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    " H9 A- ~8 _/ W- ?8 T
  176.                         SI = 1;8 B. z% D  G' A# p
  177.                 else
    8 m9 k* h' I" B: U
  178.                         SI = 0;                                /* if not, set to low */: d9 W6 X  J2 A7 |. a! `0 ^
  179.                 SCK = 1;                                /* toggle clock high */
    & B  P/ L' f, ~7 m7 \
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    3 V7 b( r2 C9 ?7 l9 _
  181.                 SCK = 0;                                /* toggle clock low */
    3 r/ q5 [+ n" W# Z+ c
  182.         }
    $ j: h% _) ^) b* n. ~
  183. }5 T. O% O6 J, E% I# C
  184. & O6 ^: Q: d0 @) [) O
  185. /************************************************************************/
    : L2 \& S: B# _% a4 V
  186. /* PROCEDURE: Get_Byte                                                                                                        */3 f  u0 S9 k+ {, [4 J7 z3 k; Y) }
  187. /*                                                                                                                                                */6 r- y* n! f9 p- g' c
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */3 q8 a! ^! {6 |+ A
  189. /* edge on the SO pin(LSB 1st).                                                                                        */# R0 [8 q! a, o, P* ~; x
  190. /*                                                                                                                                                */6 T6 V$ L* O. ?9 g
  191. /* Input:                                                                                                                                */
    4 q% t& N) o. l6 H1 B
  192. /*                SO                                                                                                                                */
    $ p  i( x- i9 Y+ o* @, v
  193. /*                                                                                                                                                */1 v7 l1 k9 k* H9 i* s
  194. /* Output:                                                                                                                                */
    2 i2 V" \  a1 E, @# ~
  195. /*                None                                                                                                                        */
    % I% X1 b2 k/ a
  196. /************************************************************************/
      ]6 O* H! D, |) ]$ X4 y
  197. unsigned char Get_Byte()
    . N7 i& R& U' s$ _' }
  198. {
    , T+ r2 }- O  |3 \& R; L* |" h
  199.         unsigned char i = 0, in = 0, temp = 0;
    ( d+ U  F* t# Y/ i- D6 g
  200.         for (i = 0; i < 8; i++)
    ) o8 v- T% d) E; `
  201.         {
    8 h4 T( D4 J  B/ ^- t# q
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */4 h6 I8 P# H8 f  A  ]
  203.                 temp = SO;                        /* save input */
    - ^+ w$ [* Z& {" b! S$ S
  204.                 SCK = 1;                        /* toggle clock high */
    ' N5 F5 n' ]( ~9 q, t) f; R$ S
  205.                 if (temp == 1)                        /* check to see if bit is high */
    ( b3 Z  W+ p+ G3 a
  206.                         in = in | 0x01;                /* if high, make bit high */
    ! N5 g7 J3 s2 [$ |4 G, s

  207. + R2 m' u0 V0 Q1 D
  208.                 SCK = 0;                        /* toggle clock low */) ^5 \* {) T! [! r. L

  209. 8 L/ A; @' y9 o8 d0 K" C
  210.         }, z7 @5 L( `( l2 ]! b: i; W  E4 z) g
  211.         return in;
    / ^- L: W* D9 y- w" _8 S' u
  212. }
    & U- R2 ^; F& V, L1 S
  213. 5 u0 R4 N: d$ A  D
  214. /************************************************************************/
    4 b: C2 y7 s/ J/ b! X9 U* _
  215. /* PROCEDURE: Poll_SO                                                                                                        */5 t$ H% c, u1 [. R: d% I6 J# n% }& |
  216. /*                                                                                                                                                */( c' o# }4 C/ I9 `$ w/ ]6 u7 l; x* K
  217. /* This procedure polls for the SO line during AAI programming                  */
    / G$ J& i# Y% h, o# H9 t5 L% S
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/4 Z& J: a& I6 Q- I2 `+ f
  219. /* is completed                                                                                                                        */; Q8 f$ J# A  e7 k, S
  220. /*                                                                                                                                                *// s' m$ R+ l( B8 j7 J
  221. /* Input:                                                                                                                                */0 F+ r5 r. K6 P2 [' v6 G9 c8 B: Y
  222. /*                SO                                                                                                                                */& \3 F' r# H' o/ r" o4 [1 }% k0 U' y7 D
  223. /*                                                                                                                                                */
    , s0 A( b, L5 ^1 M! @4 D3 c
  224. /* Output:                                                                                                                                */
    9 L. P2 |1 V& ?" q8 x( ]& `
  225. /*                None                                                                                                                        */
    : t. m/ F0 H4 f: Q+ M+ X  o  F8 Y
  226. /************************************************************************/" V3 F6 G) ~% P5 k2 G* l
  227. void Poll_SO()) P* E7 ~6 R" i2 K, G0 h. w  Z3 q
  228. {7 N. n( ?+ J* ~3 X
  229.         unsigned char temp = 0;3 k: V! ^, v! z' k
  230.         CE_Low();# r3 v' J1 h2 _  X+ `& F  `  T
  231.     while (temp == 0x00)        /* waste time until not busy *// T8 a/ n/ u2 K, n3 d! g
  232.                 temp = SO;4 Q2 P6 m( w. I- M2 u+ c4 L
  233.         CE_High();$ K" q: P* V6 g9 v, _% K
  234. }9 A7 t- {7 K7 k% Y6 _$ S. Z5 z
  235. ! X$ g, y6 y* `0 B. I6 Y/ J
  236. /************************************************************************/
    # d3 n. o9 J0 |9 _2 X) M
  237. /* PROCEDURE: CE_High                                                                                                        */
    ) o- `7 f2 h8 E6 Y5 D
  238. /*                                                                                                                                                */) L" P5 c( N4 U; Y  g8 h
  239. /* This procedure set CE = High.                                                                                */
    2 s5 I0 a, b) O4 ?/ k
  240. /*                                                                                                                                                */& K; T7 P9 _; X( A
  241. /* Input:                                                                                                                                */# u! l4 H- u* _( k5 j/ i" e8 o* g
  242. /*                None                                                                                                                        */# B# a; D, K7 m/ d  G
  243. /*                                                                                                                                                */5 O4 ?, f- K+ c2 ~7 M% ?
  244. /* Output:                                                                                                                                */. N/ |( |! `/ Q1 m
  245. /*                CE                                                                                                                                */5 ]$ e+ n5 f( r' i& d" q
  246. /*                                                                                                                                                */7 F: d2 R! }8 Z4 H, K
  247. /************************************************************************/
    / }' W0 R4 W' Z- Y
  248. void CE_High() $ g* t+ x" {' {5 w$ L
  249. {
    9 ]& S# C) O- H! q  P2 p
  250.         CE = 1;                                /* set CE high */
    8 V) S9 f2 J1 w* f
  251. }
    6 q: n/ U' b% P" `: {+ s
  252. / I" w% X( p" T
  253. /************************************************************************/
    ) Y7 j' o( ~# `+ I2 Y" h
  254. /* PROCEDURE: CE_Low                                                                                                        */
    9 R7 {& v$ x' g) R3 a! F( v
  255. /*                                                                                                                                                */& W5 b9 z8 v1 D0 Q" K
  256. /* This procedure drives the CE of the device to low.                                          */
    * B; L! ]  `/ _3 @$ a- U
  257. /*                                                                                                                                                */* W+ X9 e, N4 L; m3 u" {  j, Z
  258. /* Input:                                                                                                                                */8 Y: t# E8 N/ U1 A9 @5 o5 X' H
  259. /*                None                                                                                                                        */) x$ K0 |$ B! b* t
  260. /*                                                                                                                                                */5 M; P) S8 T  n" }2 e4 M2 k4 E3 W
  261. /* Output:                                                                                                                                */
    & H$ e, J# g: m  S% q
  262. /*                CE                                                                                                                                */" G; H: o# g3 @+ k' d: P" P" o) }
  263. /*                                                                                                                                                */
    ! \/ w5 A' q; T
  264. /************************************************************************/
    - S1 S+ ?5 N/ ]  Y
  265. void CE_Low()
    1 d/ Q. t- s) X
  266. {       
    $ ]# }( ~8 B* X4 X
  267.         CE = 0;                                /* clear CE low */
    0 L9 O. o5 @; s8 l. `- G
  268. }
    4 q+ w: L( X9 L' D2 m( K5 c! R
  269. , H, O' k8 _$ [2 E6 E, W  U
  270. /************************************************************************/
    % ~& g  u1 K, Y2 @, ?' R) {
  271. /* PROCEDURE: Hold()                                                                                                        */
    2 |+ i' P! Z! {
  272. /*                                                                                                                                                */! p" q7 r0 A6 C- Y! p& r: x
  273. /* This procedure clears the Hold pin to low.                                                        */
    & l# F0 s3 F/ b+ Y4 D
  274. /*                                                                                                                                                */$ x1 J8 z" |# o" ?4 W
  275. /* Input:                                                                                                                                */
    ) Y2 E, @' a" J
  276. /*                None                                                                                                                        */
    + E3 V$ A  s. W, Y' {
  277. /*                                                                                                                                                */
    , `% [- E4 V, t! }4 E
  278. /* Output:                                                                                                                                */) g& p5 }8 y: d) `- M+ a
  279. /*                Hold                                                                                                                        *// p" W2 O: ~7 z5 G7 q
  280. /************************************************************************/
    , A9 ]& s+ G. v' \( V# h. K5 b: A
  281. void Hold_Low()9 d* {1 D! @* b4 \$ b
  282. {
    3 `5 o7 K6 X$ Z# a, G
  283.         Hold = 0;                        /* clear Hold pin */2 e8 q& B5 O6 H# O# H0 `/ ]+ B8 L
  284. }3 n6 F3 [' s6 D- M  n5 E: V! f
  285. $ y5 v- e( v2 L$ b' W: d6 v
  286. /************************************************************************/( Y2 L0 ?. R" D' @7 t. ?9 W2 ~; q
  287. /* PROCEDURE: Unhold()                                                                                                        */
    1 ?% l1 T2 b( O# R; K. l8 A
  288. /*                                                                                                                                                */
    4 X9 j' ]  r+ G1 x" b6 m+ P( }1 I, Y
  289. /* This procedure sets the Hold pin to high.                                                        */7 L3 p& ~/ Y; h1 v* T  _5 Q$ Y
  290. /*                                                                                                                                                */
    % b  e, n* j0 Z; a) i8 R& k
  291. /* Input:                                                                                                                                */3 \7 d% |% g0 F* f5 U0 X
  292. /*                None                                                                                                                        */
    ' {4 m9 Q. l" a4 Q
  293. /*                                                                                                                                                */
    + E; w; s# `7 U8 b# F: P( m! ?
  294. /* Output:                                                                                                                                */
    ( w9 T4 x+ p& m" w- o0 \" Z2 Y  e
  295. /*                Hold                                                                                                                        */
    ( [, e# q: f/ V! v
  296. /************************************************************************/
    - O) w4 U0 J0 [0 n# g4 m7 k
  297. void Unhold()
      K' i; E' J; w! l
  298. {
    0 S) Z$ r% S6 ~& B  E+ Y+ {
  299.         Hold = 1;                        /* set Hold pin */
    + r( A8 B/ q; M0 k4 [
  300. }4 ]( K: S7 n) U. m/ B3 r' r

  301.   N; F/ s3 g8 \. q
  302. /************************************************************************/
    0 s7 W) u* U- S# N+ R
  303. /* PROCEDURE: WP()                                                                                                                */1 t, h  l3 G+ b* E6 P
  304. /*                                                                                                                                                */
    , E) D' @6 y# G; e5 q, `) X  V% w+ u1 [
  305. /* This procedure clears the WP pin to low.                                                                */$ W& j0 y8 M- N$ o/ q7 n
  306. /*                                                                                                                                                */4 k7 |7 F: K, ]6 {, K; o
  307. /* Input:                                                                                                                                */
    $ b& B: c. U/ v( W( d
  308. /*                None                                                                                                                        */  W+ w8 t& X* W" x1 h3 l" L
  309. /*                                                                                                                                                */
    : C# H5 v8 S  F
  310. /* Output:                                                                                                                                */
    * ^* n! c7 ]# ]0 J8 d# V
  311. /*                WP                                                                                                                                */9 E) a+ H3 r8 u  S
  312. /************************************************************************/
    $ n5 h- q% l7 W8 U; M
  313. void WP_Low()0 G9 o- w' ]# J9 A3 u* N# U
  314. {
    3 Y( j! z0 n. V; }& _! N3 E
  315.         WP = 0;                                /* clear WP pin */
    3 G2 H% E% T7 }4 ]$ q
  316. }
    4 V$ q4 e. W$ J2 ~: v. a4 F
  317. ' L7 z2 A  B' V3 O
  318. /************************************************************************/
    ( V' `8 P; z. ?
  319. /* PROCEDURE: UnWP()                                                                                                        */
    # V2 E! R& x) U, A& v+ d9 w) L- h* j
  320. /*                                                                                                                                                */( p8 w. b. K5 F
  321. /* This procedure sets the WP pin to high.                                                                */
    ( U  s9 P# d. [6 {
  322. /*                                                                                                                                                *// B/ ~9 C& b" t# n; i7 o
  323. /* Input:                                                                                                                                */
    & n/ C6 |! C; q% L. Z
  324. /*                None                                                                                                                        */( z5 D! F$ n  ]3 J
  325. /*                                                                                                                                                */
    * v) k4 Q& h* @7 }* {* \) N
  326. /* Output:                                                                                                                                */. v2 ]/ D5 [7 {6 P. [  I
  327. /*                WP                                                                                                                                */; j1 E+ G- B" a' {0 r" K+ z
  328. /************************************************************************/1 c+ ]& D$ o& L5 L; b
  329. void UnWP()
    $ L7 l9 g) ^8 y3 w( q
  330. {
    1 @5 _+ A7 @- D, m  O6 t
  331.         WP = 1;                                /* set WP pin */
      l' ~8 d# Y. w* l5 j
  332. }
    3 z- x; h4 h0 v1 U6 @- k1 G
  333. : r8 f! y' Q$ K5 q4 ?
  334. /************************************************************************/
    1 W1 h5 z' k2 j! M) n
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    ! u7 i  J' r/ k
  336. /*                                                                                                                                                */6 z. y2 z& J* ~+ H
  337. /* This procedure read the status register and returns the byte.                */
    ' l0 \" @% u5 H  S) f! H
  338. /*                                                                                                                                                */, p2 _9 k1 b# S% t# k6 g; i
  339. /* Input:                                                                                                                                */
    5 v# P+ N, h* g. u9 R1 y8 z. q& f& x
  340. /*                None                                                                                                                        */5 E# L# @4 @( |+ {, A  K
  341. /*                                                                                                                                                */
    . \: Y9 [3 [/ d$ V' @5 \
  342. /* Returns:                                                                                                                                */$ W+ E2 L! x- J- A) P
  343. /*                byte                                                                                                                        */7 N+ a$ U; K5 |% }2 O3 }3 \
  344. /************************************************************************/: o7 B+ X) p: u+ D- y. z/ c
  345. unsigned char Read_Status_Register(). ]( B) ], ]) }
  346. {
    3 \6 f6 |, C1 z% D8 B) L
  347.         unsigned char byte = 0;0 S9 I3 |" {6 O( ]% A
  348.         CE_Low();                                /* enable device */
      C" n% p7 L; Z
  349.         Send_Byte(0x05);                /* send RDSR command */
    % X8 m7 E' ?2 ]+ b( W. }6 V
  350.         byte = Get_Byte();                /* receive byte */
    7 P2 f0 T, t) C' o( Y# Z4 `
  351.         CE_High();                                /* disable device */
    . a) r$ F% B8 P8 o, K! R. {
  352.         return byte;
    2 E9 y* w  {5 S. n) c* W' N
  353. }
    5 ?: g) V7 o3 ^2 O; ~+ O* [# u, t( k+ J

  354. * W( M+ ]! Z/ k2 U8 f# h$ t/ d8 |) `
  355. /************************************************************************/- U' m7 J) j% @) I' `4 K
  356. /* PROCEDURE: EWSR                                                                                                                */. s$ F, w4 c5 Z- ?' e! g! x
  357. /*                                                                                                                                                */2 p0 W1 ^; b, t4 n. H4 ?3 Z
  358. /* This procedure Enables Write Status Register.                                                  */8 }' ~: Q4 f# Y* n' h
  359. /*                                                                                                                                                */
    ; x5 {2 W* K0 L2 ]+ V
  360. /* Input:                                                                                                                                */$ p' t' d1 _9 {# L" K; D
  361. /*                None                                                                                                                        */% u# v+ _3 g) a6 v$ g
  362. /*                                                                                                                                                */) F$ H" N$ G; P" [5 _1 J$ s8 F
  363. /* Returns:                                                                                                                                */7 T" J( l: o) D
  364. /*                Nothing                                                                                                                        */) V4 L9 p" s) E1 W
  365. /************************************************************************/
    & Z# \6 L# h$ c2 b) o/ m. }- s6 \& i. V
  366. void EWSR()* ]7 @3 [* r8 ^  g; ]
  367. {# i! ]3 d2 K& U  B6 N
  368.         CE_Low();                                /* enable device */9 V; U' _1 F) @4 X0 m
  369.         Send_Byte(0x50);                /* enable writing to the status register */! ?. A# Q! p. I% W" j$ _# O
  370.         CE_High();                                /* disable device */
    + g. t4 H7 Q& t" U% {. n& a  ^) o. ]
  371. }
    1 @0 C& G4 R+ ?# K1 \
  372. ) w" u/ Z- j) }6 Y. n# R/ {1 M( h
  373. /************************************************************************/$ F  I- X) W" `0 T6 D" f  p
  374. /* PROCEDURE: WRSR                                                                                                                */3 D' K& Z  W# w' M, `- j5 G
  375. /*                                                                                                                                                */- d6 @' c$ K/ x4 J
  376. /* This procedure writes a byte to the Status Register.                                        */
    3 }( A9 `' M( _  P
  377. /*                                                                                                                                                */
    ; q- ^+ u+ h/ M6 F( H
  378. /* Input:                                                                                                                                */
    : Q$ y9 F) G# n2 C4 h' x4 P
  379. /*                byte                                                                                                                        */% T- |; w3 G# Y# Q
  380. /*                                                                                                                                                */
    3 k6 B) Z% }/ b- Q
  381. /* Returns:                                                                                                                                */
    ' S1 U& ~& M- q. b% O
  382. /*                Nothing                                                                                                                        */) v* `: K- `6 d' g2 }/ F  O
  383. /************************************************************************/
    " ~6 |1 l" c0 L) {
  384. void WRSR(byte)
    9 ^8 }, d0 C" W# q
  385. {
    + ~. v1 ?8 E) L! z8 |
  386.         CE_Low();                                /* enable device */$ v, M& j6 j: ?: b' z
  387.         Send_Byte(0x01);                /* select write to status register */
    5 h7 K3 c; s5 P* b' ]" K
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    ' r7 \! a$ U5 r7 d/ \0 F7 b- ?
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */* t$ i6 p& d" K8 _, ~/ b+ s0 B" j
  390.         CE_High();                                /* disable the device */
    , c* y- o1 }5 o4 G
  391. }
    ! q) u7 c, {* q8 ]
  392. $ ?1 C3 j. l$ n; C& J) {' m/ z
  393. /************************************************************************/
    + l; x3 R0 C% g5 b* W; a# S+ V  b, c
  394. /* PROCEDURE: WREN                                                                                                                */
    & R  N% G: S5 i. N' X8 r) H& W
  395. /*                                                                                                                                                */# M4 ?1 x1 e$ e7 U1 v4 C% v' _* \
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    ' d4 A+ x" `4 ]- B: t0 R
  397. /* to Enables Write Status Register.                                                                        */
    + v7 k2 g  W/ f: N
  398. /*                                                                                                                                                */( |5 E) k' E( S3 M  S6 T) E
  399. /* Input:                                                                                                                                */
    : f4 s" }0 f6 N( r9 P
  400. /*                None                                                                                                                        */
    ; D2 ~% l( ?" o9 n+ I% ~: M
  401. /*                                                                                                                                                */
    : {' C7 l: V' ^$ P* w: B$ x
  402. /* Returns:                                                                                                                                */
    0 d) I+ @- Q8 O9 ^
  403. /*                Nothing                                                                                                                        */
    # h$ [3 x+ n+ _- n0 ]' t" D# F
  404. /************************************************************************/
    , M2 ~8 y; ]2 m$ i6 p* _" q' Z
  405. void WREN()
    : N9 e7 B0 E7 s
  406. {
    ; s8 t8 `0 r- s" o+ Z8 x
  407.         CE_Low();                                /* enable device */; R, [. f( K" U- a$ W7 y: ~* E
  408.         Send_Byte(0x06);                /* send WREN command */
    1 F- l4 V$ l1 C* }2 ^
  409.         CE_High();                                /* disable device */
    $ r1 i4 o* G( r0 a
  410. }
    0 ^/ n$ j# w* {. S" g% g# J1 N) S' p
  411. 4 g. l% C* t  ~' a+ a1 `" e& q; E
  412. /************************************************************************/9 j/ a! Q: p$ |2 ?% U7 k# z
  413. /* PROCEDURE: WRDI                                                                                                                */
    4 I* o8 Z4 j8 a9 w( l
  414. /*                                                                                                                                                */+ c8 k% n% Q3 l; F
  415. /* This procedure disables the Write Enable Latch.                                                */( y9 F3 M" Z8 O  W( e; [$ S
  416. /*                                                                                                                                                */
    8 O; u% B3 q& j. G. u- k7 P6 n7 {
  417. /* Input:                                                                                                                                */4 h# P9 t! [  o+ k
  418. /*                None                                                                                                                        */
    ' z' \+ K3 W# w7 W
  419. /*                                                                                                                                                */
    4 s1 Y' x* L- g( w0 {! w
  420. /* Returns:                                                                                                                                */" X: G) F# V1 q0 s5 r3 l9 i
  421. /*                Nothing                                                                                                                        */9 ~+ o' k2 K5 h
  422. /************************************************************************/# p4 z8 D- V5 @3 U9 ~; c) h
  423. void WRDI()
    5 o4 l+ p1 @# }4 U. c6 j3 ]
  424. {/ j6 c1 }$ h( ]3 W5 \  Y# m5 X) v2 ^
  425.         CE_Low();                                /* enable device */; ^- t+ }+ W* q& X3 \
  426.         Send_Byte(0x04);                /* send WRDI command */# ^  U3 w1 O7 j
  427.         CE_High();                                /* disable device */! D& _" M5 I. O$ M- m* X0 N' L( O4 Q
  428. }+ W. T" P( L0 {6 k4 ~: O7 K6 t1 U2 x2 w

  429.   u$ O) |  f  L3 C6 ]8 z
  430. /************************************************************************/4 J) s: @8 N3 d; |; C" E
  431. /* PROCEDURE: EBSY                                                                                                                */4 {* O* b7 T) u/ T( n  D
  432. /*                                                                                                                                                */5 Q7 j4 t* |8 F2 l
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    1 X/ a( c1 b! I: y) E' G$ G" }
  434. /* programming.                                                                                                                        */' Q2 _. u) B+ Q, Q) Q1 J7 y
  435. /*                                                                                                                                                */
    4 L/ @8 _/ Y& b* ~4 e' O8 w% \
  436. /* Input:                                                                                                                                */
    ' Q. ]. Y- |# m( q* N( X! x
  437. /*                None                                                                                                                        */% ^( B9 Y- }. [" }: n7 s
  438. /*                                                                                                                                                */8 J8 q, N* \9 |* o4 X* w- _
  439. /* Returns:                                                                                                                                */. ]5 ~: X* \! p5 X
  440. /*                Nothing                                                                                                                        */& k! t" ?1 _" u  J
  441. /************************************************************************/" {' X) @" {6 |
  442. void EBSY()
    $ k6 |  w. p' \$ h( b( X
  443. {, j2 j" i7 c, ]3 [+ X5 q1 ]
  444.         CE_Low();                                /* enable device */
    ' L( ]* V- U' j# @
  445.         Send_Byte(0x70);                /* send EBSY command */; x5 g4 H# [' v- {4 F8 m2 I  P
  446.         CE_High();                                /* disable device */
    : S7 _8 X# F2 ?& d
  447. }
    . P( r" X0 A6 a: o

  448. & q# r/ C5 p  Y
  449. /************************************************************************/) g3 K* J; j! w  y5 O/ {; R0 ?, L
  450. /* PROCEDURE: DBSY                                                                                                                */4 ?, M1 K8 F6 k; p3 D) N
  451. /*                                                                                                                                                *// n  F+ u. P2 t
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    2 A0 ]. W+ [! L6 E2 J) V" k
  453. /* programming.                                                                                                                        */, d0 A* D0 r! B, r6 e) r
  454. /*                                                                                                                                                */3 F& V/ P  H4 B
  455. /* Input:                                                                                                                                */
    * H8 T" J) {* t/ \, [" x  l
  456. /*                None                                                                                                                        */
    ; X  Q8 n2 q8 t2 i
  457. /*                                                                                                                                                */$ \# Q3 Y# }0 B' ?* f
  458. /* Returns:                                                                                                                                */8 _, e4 ~" O: d" |2 l" ~$ J
  459. /*                Nothing                                                                                                                        */
    + f' n) w. P" o7 q/ X; m
  460. /************************************************************************/
    6 U7 t% J5 b- R, g$ ]9 e; [, L
  461. void DBSY()
    3 T2 G0 ]5 {  [
  462. {
    , J' ]1 s# t. T: s
  463.         CE_Low();                                /* enable device */
    ) d% P5 N8 V- s  g+ ?
  464.         Send_Byte(0x80);                /* send DBSY command */7 _  e( m9 c# K  |  ~, j; Z
  465.         CE_High();                                /* disable device */. [+ m1 G  e0 V* }' U. x0 J
  466. }
    4 y" h3 x9 G2 p4 r: H5 G

  467. # D$ h3 [. @( b$ s
  468. /************************************************************************/
    2 N3 ?2 C: [6 V. w" m! J
  469. /* PROCEDURE: Read_ID                                                                                                        */& H/ ]  f3 {! E
  470. /*                                                                                                                                                */
    6 T) p0 U$ Y8 ~6 N
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    ( O- A& N1 r  L- C
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */# ^/ S* L) n) z; V
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    - I. m  `9 i% w9 g% ~) g
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    5 y# u, w# y2 [. Y4 A
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    ) F9 A+ U+ l) |/ |$ G: U
  476. /* variable byte.                                                                                                                */
    7 J7 p. V$ }8 D  B" N
  477. /*                                                                                                                                                */, m  \; }7 I+ u* \, `0 t. [
  478. /* Input:                                                                                                                                */
    . k( B2 J5 y3 B
  479. /*                ID_addr                                                                                                                        */2 v+ y+ [3 U, X2 Z/ N
  480. /*                                                                                                                                                */
    4 Z2 q: q7 b9 w
  481. /* Returns:                                                                                                                                */
    ' ?- x/ ?2 e  G$ h
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    & y& ^5 ^6 u  b: t9 ^% f" V
  483. /*                                                                                                                                                */, d& B9 {9 k/ V' C: |5 m2 y/ c
  484. /************************************************************************/
    + b; K+ d. d  s4 d
  485. unsigned char Read_ID(ID_addr)
    " c/ ^+ Q; |' u/ f/ Z9 @+ g2 _' A* J9 V
  486. {. V2 }4 A9 |! I9 H6 [, X% F
  487.         unsigned char byte;
    8 y4 p" v- u: H1 v; n
  488.         CE_Low();                                /* enable device */
    $ r; z5 d- x+ \, b
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    1 U- S1 X; N# B
  490.     Send_Byte(0x00);                /* send address */( ~& D! Z1 G/ C
  491.         Send_Byte(0x00);                /* send address */
    # l# r% F9 \; f- c% M
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    8 q* Z) z: F# M2 w" y% h" y
  493.         byte = Get_Byte();                /* receive byte */
    ! b7 a: z  T/ }$ h5 l
  494.         CE_High();                                /* disable device */: {# Y  ]8 u% _+ V6 J
  495.         return byte;
    # A' [3 [7 O- M' T% ?: ]
  496. }
    : p( r% e; z1 G; B  x

  497. : d8 I6 @/ q' F, l6 Y/ j
  498. /************************************************************************/  |! L; d# H1 W" M+ K
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    ) m/ e3 ]) D, {+ r& ~, m
  500. /*                                                                                                                                                */8 a+ w: ]+ l0 [& m6 w" n$ X  s, O
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  *// g. w2 m8 a( P( M* f
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    ; A7 C9 E: F/ J% Q
  503. /* Please see the product datasheet for details.                                                  */9 B1 E0 R& x  |. B. J- ?
  504. /*                                                                                                                                                */
    & `1 ~) @4 s3 ]; _% F0 @
  505. /* Input:                                                                                                                                */
    7 R; s/ U9 ?: f
  506. /*                None                                                                                                                        */
    - W) N( A1 |6 A4 a
  507. /*                                                                                                                                                */$ {- z( }/ Z$ O7 Z9 w/ t
  508. /* Returns:                                                                                                                                */# k5 R) m+ V& D( r1 \
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */% T: q) {6 J9 r7 V' Z
  510. /*                 and Device ID (8Eh)                                                                                        */; X' n3 V( C) Q! \7 g5 b5 Z
  511. /*                                                                                                                                                */
    ) W# o7 G% G0 K$ P* v' N5 G& }  ^( V
  512. /************************************************************************/" Y3 c) K. m% t! `7 r8 @' _- o  n. j
  513. unsigned long Jedec_ID_Read()
    # ?# B, W7 S& `
  514. {/ p4 j  ^9 p- {5 \- d, ]+ {
  515.         unsigned long temp;
    ; a) i) q& N5 W( Z/ o+ P
  516.         1 G; S) X5 U" z
  517.         temp = 0;/ c. z1 a. a7 `6 P# X: E. Q

  518. 6 K6 F0 ^- q) f; U1 n0 J  z5 P4 g2 y
  519.         CE_Low();                                        /* enable device */
    , m: H' y2 u4 u# h: u+ ~4 @: F  f
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    * T6 q3 v: R  F; F. H3 m
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    0 Y+ W; f" g  c9 G- v5 J
  522.         temp = (temp | Get_Byte()) << 8;       
    ' m1 @+ Z# a2 r7 [! R( y/ x  h
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */* I; ?0 R/ o6 z9 M  d
  524.         CE_High();                                                        /* disable device */0 J: y; r: K/ @) x! J5 K
  525. 4 p! i1 k: z- T& |3 r
  526.         return temp;  L7 t$ E( M5 n. q
  527. }, g; T2 C2 ^! {7 F& p

  528. : O- h; w0 a8 L2 ]$ b
  529. /************************************************************************/
    : V& z! y* i, e
  530. /* PROCEDURE:        Read                                                                                                        */
    2 t9 [' i6 j, i
  531. /*                                                                                                                                                */                0 {+ w' A% F. D* @1 T$ C8 q1 k
  532. /* This procedure reads one address of the device.  It will return the         */
    / w0 @- z* D5 U6 \: m+ t7 k0 L4 x
  533. /* byte read in variable byte.                                                                                        */) p! V+ z6 E8 g6 x/ T& K
  534. /*                                                                                                                                                */" x$ V/ F: k" R4 H  u$ m  n1 b, d
  535. /*                                                                                                                                                */# z, L$ ?: \) {# [& ^" n
  536. /*                                                                                                                                                */" S0 ^$ k6 }4 \$ g
  537. /* Input:                                                                                                                                */
    9 R6 R, I/ `* ?8 f% Y
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */" }1 ~% N9 K0 H( J% A
  539. /*                                                                                                                                      */
    # I. X+ d8 ^, F: k4 z
  540. /*                                                                                                                                                */9 L0 F. }8 Q  T6 H8 ]
  541. /* Returns:                                                                                                                                */
      M; q8 e6 Q# ?; C6 O6 g
  542. /*                byte                                                                                                                        */' `' a9 |5 j; x2 ~; y
  543. /*                                                                                                                                                */
    6 i) l( T. r% q' Y. H
  544. /************************************************************************/
    % B. W& C7 f; r! ]6 r8 O5 ]0 J- G
  545. unsigned char Read(unsigned long Dst) # M+ u; \8 k' @
  546. {* s1 g8 F' x1 H$ f
  547.         unsigned char byte = 0;       
    + M- I" J# x2 [( ]2 A9 L
  548. * [3 H( d7 S. T9 w, g# G% W. a, I
  549.         CE_Low();                                /* enable device */
    ( j2 d( Q7 T  R* p! o' {
  550.         Send_Byte(0x03);                 /* read command */
    . Z' R# Z1 x5 u/ V. ]8 ~+ b
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */! Q  j4 C7 h* a. `0 t* \
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));" Q9 p7 X4 n. X) i# C4 f& i
  553.         Send_Byte(Dst & 0xFF);
    9 }; j3 g2 b; i0 V! y8 `
  554.         byte = Get_Byte();
    8 ~! f5 F; J( |- @# ^
  555.         CE_High();                                /* disable device */
    " I7 f- B. }9 i& l/ _0 i; Q6 O7 O3 t$ }
  556.         return byte;                        /* return one byte read */
    , W4 [- N: K" {8 m5 ^' S
  557. }5 `+ I! O0 O# y" y( l

  558. ) h9 g. ~& X. B' j. h
  559. /************************************************************************/- q9 m7 ~9 ~; _( q
  560. /* PROCEDURE:        Read_Cont                                                                                                */9 k+ T) v& Q, k  N' [, `3 v
  561. /*                                                                                                                                                */                , m% c6 ^( {' q
  562. /* This procedure reads multiple addresses of the device and stores                */5 d& b! B! A! U; P% X7 a; V
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/3 F) Q. l1 @& \/ A
  564. /*                                                                                                                                                */
    ) u/ N/ N7 N+ a/ j! d
  565. /* Input:                                                                                                                                */( {+ j, k+ ]( ?- R1 A0 E( {' s
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    $ b: }  j5 H% o' ^2 {  Z5 J2 e& y
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */) w* ~# n" j% O5 |3 }7 U, W
  568. /*                                                                                                                                                */3 o5 x* W  V1 O6 H" j* c8 s3 S) R
  569. /* Returns:                                                                                                                                */, ]! z; P% Q7 z# o/ H7 P7 y0 l) X
  570. /*                Nothing                                                                                                                        */* d( h9 y9 @2 U. ~9 Y' w: `
  571. /*                                                                                                                                                */6 Q8 ?' p2 @( m( j
  572. /************************************************************************/
    8 P# i$ b3 I1 q- @% y  ^( t
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    . T" Z' j: d- j( B$ s" p
  574. {
    ) @( {' V* q/ _0 X6 O6 [& O
  575.         unsigned long i = 0;. @3 Q6 t) ?: A3 c; B# }
  576.         CE_Low();                                        /* enable device */: B0 |+ u- O; m1 L) y
  577.         Send_Byte(0x03);                         /* read command */
    & A2 ?0 l! Q2 O5 M. ]  Q5 I
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    . U# L; i/ f- l
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));/ p" m$ K, |" B7 ^
  580.         Send_Byte(Dst & 0xFF);- i" G. C& G5 Q  Z5 \4 n. h& ?1 O
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    0 D: J3 H" v6 O4 X) i* R; g- f
  582.         {
    " H6 R9 A2 |- q4 Q- m
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */: I1 D* r  P2 I% b/ j
  584.         }4 N+ m. V9 V0 x, I
  585.         CE_High();                                        /* disable device */3 j4 C5 m3 W* W4 X, ^
  586. + W5 `7 a  R) x. c8 }% C3 @
  587. }
    # u, o+ S) n1 q6 |1 z; R* ]) }
  588. 2 r! M! p3 \, `. v
  589. /************************************************************************/
    & S( w/ q0 r# H  n
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */( w  R7 M1 [& A: o+ ~
  591. /*                                                                                                                                                */               
    " z: u' D% E) K0 \
  592. /* This procedure reads one address of the device.  It will return the         */( s6 l% J; q9 h7 x) K
  593. /* byte read in variable byte.                                                                                        */* _9 L8 ~& V" O9 L
  594. /*                                                                                                                                                */
    % V  v0 B# H0 J/ A! Q8 m( f
  595. /*                                                                                                                                                */7 W, Q2 }" z$ a- ?5 D
  596. /*                                                                                                                                                */7 K! L! R, H+ @" h
  597. /* Input:                                                                                                                                */
      C+ l0 q- a# ^
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    $ a0 ^* d0 r8 s+ M$ B' `; B
  599. /*                                                                                                                                      */+ C* s; Q6 l4 ?  y8 j% i
  600. /*                                                                                                                                                */
    / Y; H6 F. G1 g
  601. /* Returns:                                                                                                                                */
    8 l  J" n/ }/ A& M. z
  602. /*                byte                                                                                                                        */0 i0 y! [6 D- J5 [
  603. /*                                                                                                                                                */
    ; Y' s  a5 n( b9 x
  604. /************************************************************************/+ y! `  n6 |2 w- p
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    9 ]9 I8 O$ D$ U& u* e5 U) p5 ~
  606. {
    1 m" w$ y& v9 e7 m1 {
  607.         unsigned char byte = 0;        * Z6 A' E4 e/ e3 P

  608. - L" u) N9 h# {5 @
  609.         CE_Low();                                /* enable device *// D3 u6 p8 H( J% m, Z
  610.         Send_Byte(0x0B);                 /* read command */
    . f' x3 G, Q# A  R9 j# r* b
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */9 M0 I% b/ r9 J
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    1 U' Q5 M: U8 u  g/ K5 D$ l
  613.         Send_Byte(Dst & 0xFF);
    : W1 U6 j8 H7 {8 p' b
  614.         Send_Byte(0xFF);                /*dummy byte*/
    / _5 R/ K/ s! f% ~
  615.         byte = Get_Byte();! o" ]# D8 B! D2 n
  616.         CE_High();                                /* disable device */( Q8 ~8 N" c7 b: r3 f1 M: a% x
  617.         return byte;                        /* return one byte read */
    0 J. J' F& |5 g- H* x+ w6 z5 s
  618. }
    * H  ~' R3 s  g4 M$ `2 [
  619. . r: L% o/ o1 D
  620. /************************************************************************/9 w5 z5 K9 S# n1 [' f
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */8 X& b& V' A4 T! h2 D6 A
  622. /*                                                                                                                                                */               
    ( _* r0 J: r9 k6 L/ Q5 a
  623. /* This procedure reads multiple addresses of the device and stores                */( i. E: z. d5 Q9 W
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    4 T  W+ o# ?9 j
  625. /*                                                                                                                                                */
    7 E6 z' l8 ?& u0 d" M$ J8 u$ Z. D
  626. /* Input:                                                                                                                                */7 H/ s. h) z  m& }. g+ S
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    6 V0 \, z8 p* l# }5 R
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */1 N: ?  w2 E9 E4 T+ L0 f
  629. /*                                                                                                                                                */1 V% f5 [9 G% @1 Z6 j
  630. /* Returns:                                                                                                                                */
    1 L" b6 h7 X( i
  631. /*                Nothing                                                                                                                        */
    & N, a  M& i$ K6 C, x* v+ N9 P) Y
  632. /*                                                                                                                                                */5 f+ O' I) S2 D1 k: _+ N; r) w
  633. /************************************************************************/) Z8 ^6 }! |* R: |7 q$ ?2 j
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes). g; w' S; n9 T
  635. {% o$ G8 a4 t3 T# s% f
  636.         unsigned long i = 0;
    7 `7 E9 c% c4 i6 L
  637.         CE_Low();                                        /* enable device */: x; i! K6 O! X* S
  638.         Send_Byte(0x0B);                         /* read command */( _" f; w* D5 K- t% r! i
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! Y2 y  A. `" O" D; S! x
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    7 S! Y& u0 C4 H; O' j  @; U8 Z
  641.         Send_Byte(Dst & 0xFF);
    ( T# \( X# N) k* y: f# I+ q$ p
  642.         Send_Byte(0xFF);                        /*dummy byte*/
      _$ I- t# V9 M" W
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */  V! i/ Z1 ~8 x
  644.         {
    ! d$ j: B0 ]: v0 w2 d
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */7 T: O1 _6 D  K6 j1 U( j
  646.         }7 F& ^/ B* ]9 A  |& a1 ]
  647.         CE_High();                                /* disable device */
    6 @- i8 U% I' X! d2 [
  648. }
    / ^/ ^9 O9 r# C* d9 q

  649. ( v$ o4 H" _: N
  650. /************************************************************************/# m( q2 f) x' O* x5 V: V8 n4 [
  651. /* PROCEDURE:        Byte_Program                                                                                        */8 [8 m5 _* w- m5 ?9 |  \; ?
  652. /*                                                                                                                                                */
    6 g0 }  X! W% X0 _" Y  p
  653. /* This procedure programs one address of the device.                                        */
    0 G. h; w" A3 g$ T/ Z& S2 g
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    % M  J  d6 v6 o, H8 ], f
  655. /* block protected.                                                                                                                */
    6 ?: R: \9 z+ g- {, F
  656. /*                                                                                                                                                */
    " y- E. |9 J0 [9 M
  657. /*                                                                                                                                                */
    , V9 G8 D' W( \: i$ N5 e
  658. /*                                                                                                                                                */
    ) X3 _- G" [* Y$ i0 B$ V: ]
  659. /* Input:                                                                                                                                */
    * d+ z& I3 e% G2 ^
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */5 i0 d$ s" Q! Q8 g6 A7 ~- Y
  661. /*                byte:                byte to be programmed                                                                */5 b- t4 R9 |: I" d5 k+ O
  662. /*                                                                                                                                      */
    2 N, f0 \, r. \" |2 P+ e
  663. /*                                                                                                                                                */
    / W" v+ @! k" e2 v9 X3 m7 {" W
  664. /* Returns:                                                                                                                                */' v0 ?: z  M9 c4 K9 E$ W' E# w
  665. /*                Nothing                                                                                                                        */# m; j2 r' M! b
  666. /*                                                                                                                                                */- p: X4 f5 J2 D! I. y
  667. /************************************************************************/; u, F  Q* z, w+ P/ A' M8 H; ?% k
  668. void Byte_Program(unsigned long Dst, unsigned char byte)8 D' L& J7 v3 w6 w/ c( K4 N! b6 F
  669. {  r, v% S- z( ^4 _
  670.         CE_Low();                                        /* enable device */% ~" A) Q( o% ^
  671.         Send_Byte(0x02);                         /* send Byte Program command */4 S+ L; y( H/ X. B- O: V) J
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    / b4 q) V: h7 T, x7 U6 y# ]
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));; C* H6 i8 ^6 g, n- j0 `' _
  674.         Send_Byte(Dst & 0xFF);3 V) S5 r; E+ f- `/ y
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    6 w0 ]7 O9 G" e7 D# r5 E) @- @
  676.         CE_High();                                        /* disable device */& _2 T) c( r) m8 Q- ~
  677. }1 I# Y; Z5 S/ b' s" D9 x) O) o

  678.   Q3 o: S1 E2 h, R  ^
  679. /************************************************************************/$ `+ A* c6 ~) E% O
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    6 R, r* W0 z& T
  681. /*                                                                                                                                                */
    + U7 v+ B9 O! x' }( T" e
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/2 z; p6 G2 x" T! M- f. U& p
  683. /* the device:  1st data byte will be programmed into the initial                 */- |4 y- k/ d1 c0 \* C. G5 e
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */8 k; R6 c  u# U5 c
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    # `% c: v$ ~: S* q9 s5 u/ N9 B
  686. /* is used to to start the AAI process.  It should be followed by                 */
    " j1 n- y4 O: p! Y
  687. /* Auto_Add_IncB.                                                                                                                */
      {. w) p9 s" _+ p. B
  688. /* Assumption:  Address being programmed is already erased and is NOT        */% W0 g0 c! ~) z5 Z! c0 D  s
  689. /*                                block protected.                                                                                */
    ( [: Z% k) P9 N& r5 a
  690. /*                                                                                                                                                */
    # B$ U# U5 [# i7 b5 l5 e
  691. /*                                                                                                                                                */
    ' l. }6 T/ |9 n" C1 ~/ }
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    0 Y( ?9 V9 R; X' N8 x( [" z
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */0 c( C5 j* S) U
  694. /*         unless AAI is programming the last address or last address of                */
    0 e" ]$ |# i, `( I: z0 ?9 z
  695. /*          unprotected block, which automatically exits AAI mode.                                */2 b/ j  M; n8 ^+ P' V' X& {
  696. /*                                                                                                                                                */, w& |/ \) n) Z9 w* r1 M* H
  697. /* Input:                                                                                                                                */
    . {0 V; b% l8 C" b  I) f- }  E- Y
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */3 T7 T4 K5 Y) n  M1 z1 ^% U$ w
  699. /*                byte1:                1st byte to be programmed                                                        */
    : n: F; X# Y" |6 c
  700. /*      byte1:                2nd byte to be programmed                                                        */
    ( N9 p2 u$ X" _* P
  701. /*                                                                                                                                                */
    1 S% f+ [2 x- l2 ]4 b, P% u+ G+ F
  702. /* Returns:                                                                                                                                */
    & s/ K9 c  W. D4 ?  }! r' E/ \. T
  703. /*                Nothing                                                                                                                        */0 H5 q4 F" z  m, F" @( h& U5 z0 c
  704. /*                                                                                                                                                */) w" y; b2 N/ B' W$ \. P1 s
  705. /************************************************************************/- Y/ d* }- U0 J) K/ k( h+ k" w
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2): k9 \2 v* E) \/ S( d1 n
  707. {
    * D# X3 S7 ?( }/ X; [( P  Q
  708.         CE_Low();                                        /* enable device */- i6 E. L) j4 e9 X# B; |1 e
  709.         Send_Byte(0xAD);                        /* send AAI command */7 C# I5 @& l# v. @# m# B& @5 i9 m
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ! r' N: L% [7 A  G: `6 v' {- Z
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    / H; F! K. X! v$ c9 F+ u& h
  712.         Send_Byte(Dst & 0xFF);
    - s9 @% o* X+ N( h2 W4 g7 p! y
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        9 o% W+ V4 T1 o, {! m* {; K1 ]
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */. C3 p+ s6 V) F0 ~9 T
  715.         CE_High();                                        /* disable device */: Z4 Z- }  y% i" j
  716. }; b& x; F0 _" }) Q# R* k% X
  717. # n0 u% x4 J3 e. h
  718. /************************************************************************/) B* f: F/ ^$ Z6 g' }' @
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */7 @$ w- e+ \) {9 J+ A4 ^
  720. /*                                                                                                                                                */* A; S5 f% B2 H4 P
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    ! l0 L5 f( T$ G# w+ B
  722. /* the device:  1st data byte will be programmed into the initial                 */. ]' C! K& q) Q% W
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    . L( B; g& f0 J. ]6 _0 P3 {
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    7 T' n- l) @+ l
  725. /* is used after Auto_Address_IncA.                                                                                */( p+ ?9 I( j& Y3 Q0 I  U7 m
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
      l8 \4 E0 S8 v# T; s
  727. /*                                block protected.                                                                                */* h9 V* ~  R& N% }" @, J
  728. /*                                                                                                                                                */7 z* X. B! A' ^# |9 w/ A/ ?" F5 D: z4 K
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    1 H8 l8 U3 r$ i2 Z4 H& i$ b
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */' R6 M4 B# r5 K% }
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */0 T" ~% k' F) v& m2 R# o
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    3 F& Z% y, Y' v  D9 a
  733. /*         last address of unprotected block, which automatically exits                 */
    $ m: _  T" G& b* T2 ?" T
  734. /*         AAI mode.                                                                                                                        */- }8 z8 J$ \; }, I, j! s% Z
  735. /*                                                                                                                                                */
    % f* H: h8 Q& |+ ?! E/ g; m) p
  736. /* Input:                                                                                                                                */; u; v5 W) w4 u. P, P% v9 Z5 N# M
  737. /*                                                                                                                                                */7 ?6 G0 w$ J( F0 \% T, b
  738. /*                byte1:                1st byte to be programmed                                                        *// j1 U" _5 Y8 E8 b( S* I
  739. /*                byte2:                2nd byte to be programmed                                                        */- i+ M. Q6 i& K) ]; d8 I
  740. /*                                                                                                                                      */# C& @6 R9 _6 @" W; w! D
  741. /*                                                                                                                                                */
    ' P" q( F, }- W
  742. /* Returns:                                                                                                                                */1 n6 l  A, V2 u7 a  S/ s! t
  743. /*                Nothing                                                                                                                        */
    " z( ]- f0 D% W1 q
  744. /*                                                                                                                                                */
    ! s7 \3 d( v. _
  745. /************************************************************************/
    : h0 C7 Z& v  v
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)  v: I3 X1 G" Z, G( U% @
  747. {+ F: E9 m# o9 s7 O- [" q
  748.         CE_Low();                                        /* enable device */' G1 ?/ P; N) ^3 n; k
  749.         Send_Byte(0xAD);                        /* send AAI command */5 w& j) h( m9 D* `- r7 {
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    " E3 F- t0 E3 y' R/ e# I
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */* s9 H# x3 C8 a) W; d1 Y
  752.         CE_High();                                        /* disable device */+ `; P% m4 [) c" o% H
  753. }5 G& F% c5 ^7 |8 F

  754. - Y4 i2 Q( r5 ]
  755. /************************************************************************// W6 r( ]" Q& @5 h
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */! c) }( i& n% a9 p8 c( x* i! W2 b
  757. /*                                                                                                                                                */
    ; k' q& S/ D: D/ I6 o
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */% M6 U" P7 X; Y$ b% }1 N
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    & |9 F( b$ w& q" q+ s2 e
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    , R0 n# p2 A( v# y
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */* a8 P, ?) i% ]- g. d
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */! Y) y# y+ F4 {( d0 v% a7 V# G
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    - Q" k4 {2 p& [0 k7 T# }
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    ' H; P$ p. a  q# l5 Q- M/ ?; V8 H  Y
  765. /* Assumption:  Address being programmed is already erased and is NOT        */) p) R! u% I( q9 k# K, h4 R& @
  766. /*                                block protected.                                                                                */
    9 R( A; d' R5 R6 V" R# P
  767. /*                                                                                                                                                */
    7 P8 j$ r- A& G: @) x& N+ i
  768. /*                                                                                                                                                */+ S) o, O8 g  R3 E. w( R2 f
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */9 D& x% h0 K: B# I1 c" W
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */# H: T  ^# K. T* F! {4 X. g
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */$ e1 h/ m* Z0 v1 S3 Z# E
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    ( o& {- Z) B+ i+ a
  773. /*         last address of unprotected block, which automatically exits                 */
    4 c: u4 O! r8 L# B# W1 X
  774. /*         AAI mode.                                                                                                                        */
    . G# ^9 [' q7 ~  n$ D6 e
  775. /*                                                                                                                                                */
      X  D! ^8 a' R( {% t
  776. /* Input:                                                                                                                                */
    - j7 _. C6 w" \
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    / D$ ]2 D/ [* V: q, b8 O' A  a( v6 e
  778. /*                byte1:                1st byte to be programmed                                                        */" r* ?  Z. f( z
  779. /*      byte1:                2nd byte to be programmed                                                        */4 R: J  Z1 @2 |6 N* V3 z6 A
  780. /*                                                                                                                                                */+ o; [0 I- X* e8 Z: ?$ L! \4 w
  781. /* Returns:                                                                                                                                */
    . a/ v( q  C: B6 @% l/ |$ W3 z
  782. /*                Nothing                                                                                                                        */% j' K$ a3 `1 ~  _5 e. `4 O
  783. /*                                                                                                                                                */
    5 H& J2 j. m/ y( o
  784. /************************************************************************/
    ( M. s8 A& ]1 k3 J8 S
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2): J& M; M7 D7 H
  786. {
    , ^4 u* K( B9 k+ V2 N
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        * I* P) L, n2 O: p2 w

  788. $ }/ e# u+ E6 b5 \( D% @& D
  789.         CE_Low();                                        /* enable device */
    ' V9 z- B! H, h* E  ]$ m2 r. V0 V
  790.         Send_Byte(0xAD);                        /* send AAI command */" [, i. [+ ]6 u, K3 b! [
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    & x/ R3 c3 D6 a5 L& r- F
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));2 h% ^! s, Z+ ^( _5 o/ P
  793.         Send_Byte(Dst & 0xFF);
    - B( y. }0 G0 v" c( p2 A
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        % Z7 P; s4 W$ T2 z' X3 c2 R
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */! p0 I+ R( m+ G* K$ A  |
  796.         CE_High();                                        /* disable device */
    ! m5 m& ~' H2 h8 I& c; Y
  797.        
    % {) k7 L( Q& F5 c  P! s
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    7 Q5 A- C% S+ E* k1 I, f1 E- F, n( W8 n
  799. 4 w  @. B  v; K/ I
  800. }# r& n( ^$ N9 l% I1 v! O# ^9 O; ~

  801. 7 ]* ]& R! F6 h3 ?1 x
  802. /************************************************************************/
    3 V$ `( j0 `3 |; n; n3 b3 v
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */, c. V' N, m7 b) g# i
  804. /*                                                                                                                                                */' w, b7 z6 j: f* H! E$ u' C
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    + o9 _1 W) t* N- _" c3 ^
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */, I$ A' o. E+ e6 K% C! e% ~4 e
  807. /* AAI programmming is completed.  It programs consecutive addresses of */4 c& ]3 X0 y* B6 |
  808. /* the device.  The 1st data byte will be programmed into the initial   *// h6 \; P2 v3 j- m0 l& Z9 c* _- K
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    ! H# p4 o& V. o3 k! R" U8 P- e
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */1 l* @6 g. _( }7 i5 a
  811. /* used after Auto_Address_IncA.                                                                                */
    ' K" \) v* H) v6 k
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    $ \  H4 }0 M+ r8 T4 u, z: `, w5 f) _& E
  813. /*                                block protected.                                                                                */8 Q$ i  g9 k4 a7 W1 d- h
  814. /*                                                                                                                                                */7 q% d* I+ A2 m' ?3 l
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    1 b( H0 l% \& {8 C
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */2 C0 h2 U* g& z" d% k# U
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */2 d: R9 F& ]. k+ I4 l& w1 v/ B
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    2 [- L+ a2 k  P  K" o9 B, n+ m9 X- ^
  819. /*         last address of unprotected block, which automatically exits                 */
    ! C3 G3 M* p0 e2 `. |" L% ]. [
  820. /*         AAI mode.                                                                                                                        */: j( W( L+ R! @  M
  821. /*                                                                                                                                                */+ n3 C# G/ {6 N4 o" y
  822. /* Input:                                                                                                                                */
    7 ^3 D# M9 B: y0 h6 T, W! G1 W
  823. /*                                                                                                                                                */
    ' _1 U) a$ b. G" O
  824. /*                byte1:                1st byte to be programmed                                                        */
    ; r- I/ {$ E7 P: j) ~' B7 `' v
  825. /*                byte2:                2nd byte to be programmed                                                        */( P1 Y7 z" O( j9 f! S' K
  826. /*                                                                                                                                      */! x# I. T" N% O' l9 V- W
  827. /*                                                                                                                                                */
    - [( N$ U) y1 H+ y6 _! M' b
  828. /* Returns:                                                                                                                                */
    * C0 X2 ~1 T: ~- V4 B& O
  829. /*                Nothing                                                                                                                        */0 ?3 p, z4 I" h/ C8 I
  830. /*                                                                                                                                                */
    # R! o, g) M" K6 s$ q; {
  831. /************************************************************************/
    6 d9 A6 B1 K' X7 l
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    - H/ t% q4 A' r  t* c/ k& y
  833. {" }' d+ |4 S' R9 ], x
  834.         CE_Low();                                /* enable device */
    & u* m& t4 C6 q; @$ ?
  835.         Send_Byte(0xAD);                /* send AAI command */) R, c4 }1 g5 a* m" }
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    ) L* d8 @3 K' X9 p5 X% j
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */3 S- V* R! L; n8 J( a- E$ L
  838.         CE_High();                                /* disable device */
    0 f; X! \) }4 {  S3 Z
  839. ; m3 C8 _6 u% D3 x( ?
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    ! ?. s7 i6 N3 w  z; I. y) |

  841. 7 S8 s" ^& [+ u( P
  842.         WRDI();                                 /* Exit AAI before executing DBSY */3 e- p: U3 C2 V8 B7 z: o: s/ ]
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */; E: E. ^: k& f5 J. C5 D& y
  844. }  [, l1 n0 N2 X/ i
  845. 4 f3 K- q2 A  t9 \. u
  846. /************************************************************************/
      ?8 X4 W8 B) H5 Q. k
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    * `& O' z+ i: R5 b3 F9 |, ~
  848. /*                                                                                                                                                */
    . E9 V+ l1 G2 J( g( m! O
  849. /* This procedure erases the entire Chip.                                                                */
    # _/ F' X! F& x5 b" ^, J9 _
  850. /*                                                                                                                                                */
    $ z1 Z  s! b/ M7 s, u
  851. /* Input:                                                                                                                                */9 K" @  y3 l/ w/ S9 C% M  t
  852. /*                None                                                                                                                        */  _$ e$ @. \. Y3 _) Y
  853. /*                                                                                                                                                */  S# Z+ P3 _/ f7 C% G- z% L
  854. /* Returns:                                                                                                                                */" J" ^5 ^# l0 N, H
  855. /*                Nothing                                                                                                                        */8 [" h; L( \8 k6 x% R; [
  856. /************************************************************************/8 Q# J- K( t1 J; @1 c$ L
  857. void Chip_Erase()
    + g- ]8 K# o5 H7 u
  858. {                                               
    ' v5 K) t5 Q/ [) I2 J7 P2 ]3 z' N
  859.         CE_Low();                                /* enable device */
    . q& v% m0 `& X, c8 ^$ d2 N
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    % k% i( j0 G% e9 `" h9 H3 T( I
  861.         CE_High();                                /* disable device */
    9 W0 x, n1 D% s6 _5 d' ~" u
  862. }: s/ ]% v. X2 N+ e1 _3 h
  863. + [5 X) g! x" n) c
  864. /************************************************************************/. A- l/ M& ]$ T) v! U
  865. /* PROCEDURE: Sector_Erase                                                                                                */5 p2 t' D8 G0 t5 T4 I) j5 ^
  866. /*                                                                                                                                                */
    . H6 V* i8 z& v; T6 F
  867. /* This procedure Sector Erases the Chip.                                                                */
    " ^; T6 C1 c. e6 n8 c$ I
  868. /*                                                                                                                                                */
    # L9 }$ v$ L1 w: i5 D$ `/ @( ]
  869. /* Input:                                                                                                                                */" @: C, a$ x' m" {" J8 U
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    9 u# z% Q; v8 }& ]
  871. /*                                                                                                                                                */  e+ t! S; H) w$ e) @2 B
  872. /* Returns:                                                                                                                                */3 `4 \* ~2 H& h! T2 r' y
  873. /*                Nothing                                                                                                                        */
    1 ?) T6 R9 K- n8 e3 h
  874. /************************************************************************/$ s/ k: u  b  F
  875. void Sector_Erase(unsigned long Dst)
    0 z, o3 s4 |, A
  876. {0 m$ g3 j' w; |0 m

  877.   z2 C3 A% z  T* A

  878. ; C0 k" m6 E8 e) w4 }: B5 A. w4 r
  879.         CE_Low();                                        /* enable device */0 m5 X/ Y, q& d
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    # Z) J8 I* B- s
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */7 B% G; H6 W# k! {5 g: a
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));1 r" u! f5 X  z  h
  883.         Send_Byte(Dst & 0xFF);, i, {* T5 j  m5 Q9 N* I" D
  884.         CE_High();                                        /* disable device */
    # E$ D& O% n9 B1 k) P  K
  885. }        ! |- d  y4 ~8 d1 V! s0 ^

  886. $ R" D0 J! i% ?) w
  887. /************************************************************************/* @, c6 c% {" C! |
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
      [* J9 x" h' n2 V  E! R- W' C! h+ Z
  889. /*                                                                                                                                                */
    # M* {; R2 ~6 \. k* B- E
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    - Z4 L7 L3 H2 |' C  Z% f8 s/ d
  891. /*                                                                                                                                                */
    / B" d: @0 t$ i4 [' K7 e5 _
  892. /* Input:                                                                                                                                */3 k' m9 f) S* J
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    5 b6 @7 m0 j' F& B6 U# y& _
  894. /*                                                                                                                                                */+ p- C- p) D* A! x
  895. /* Returns:                                                                                                                                */2 L+ j$ |( O' e! e- f6 y; S
  896. /*                Nothing                                                                                                                        */, T: E/ O9 }' J
  897. /************************************************************************/
    ( C5 F: ~: ^5 S6 Y
  898. void Block_Erase_32K(unsigned long Dst)
    # y, p8 ?9 z$ t+ g: }
  899. {1 c9 {" m. h0 Z/ h% l4 |) B
  900.         CE_Low();                                        /* enable device */
    0 _) ^) b- {! Q5 J6 C; y2 S
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    1 F! `/ {1 j  b3 T
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    + r$ }3 q5 }: ]- P1 I) y; `+ m
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));. o  o+ _: A7 l$ e8 i
  904.         Send_Byte(Dst & 0xFF);
    & s# t: H! `4 L- h  [' {; u2 q
  905.         CE_High();                                        /* disable device */
    # T0 x  v1 x( e2 T
  906. }' N0 A. n) U9 A' o& R
  907. ; _( o" Q  f% {0 ?. o" U; w* X
  908. /************************************************************************/
    # v7 f6 t# Y+ p1 D$ s# }
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */' F0 ?) P5 q, Z- ?
  910. /*                                                                                                                                                */
    + y3 O+ X6 {& o3 X9 ]
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    2 g$ m; N- S- o6 L5 m
  912. /*                                                                                                                                                */
    # F  ^/ X- U! S9 ^: B0 a
  913. /* Input:                                                                                                                                */
    % {8 B# @9 \1 V9 H4 j# z4 M8 m
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */$ ?7 w+ K$ Z- x* [
  915. /*                                                                                                                                                */3 T. h+ A3 Q$ t$ E: g/ b3 D
  916. /* Returns:                                                                                                                                */
    : f3 i, t# K0 w$ w; G
  917. /*                Nothing                                                                                                                        */
    1 K) D& j8 n: x: v1 [( X* O
  918. /************************************************************************/) W( i' `) u( H$ }$ a; L
  919. void Block_Erase_64K(unsigned long Dst)5 H0 ~0 A0 A7 W- |, u# ^
  920. {
    : ?8 o. k) h) [9 Q& x" v; p
  921.         CE_Low();                                        /* enable device */, J1 @3 W# O( S. C5 `
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */% g( g3 T; p6 H( V9 t7 P8 I' {: F8 N( }
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    + ]# q$ u) I6 h5 s1 m9 O5 K
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ) D( g( J# `7 i5 a; m2 R
  925.         Send_Byte(Dst & 0xFF);" r2 ~" s, w8 Z7 r
  926.         CE_High();                                        /* disable device */3 E( i' ^% c6 V* S* Z# r: _' Z5 ~
  927. }" A4 g. p9 S/ \/ L

  928. 5 M+ `$ k* E" w* f# v" n
  929. /************************************************************************/) E6 ]5 M( {: r6 X
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    . }( m( j/ e+ g0 i# w1 c, ?
  931. /*                                                                                                                                                */$ ~" v& i6 [7 g1 _( W8 e2 r7 c7 @
  932. /* This procedure waits until device is no longer busy (can be used by        */
    6 ]/ O; C6 ~5 G' f6 G
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */; F5 V. g1 m: h; Z7 f2 p6 y
  934. /*                                                                                                                                                */- c. _) v+ p9 Y/ I8 S) V
  935. /* Input:                                                                                                                                *// ]: n( _0 f% y- O2 ?
  936. /*                None                                                                                                                        */; A& c) ^- S- h- @! V7 w
  937. /*                                                                                                                                                */6 Y+ \: t+ c& p# r) C" x
  938. /* Returns:                                                                                                                                */
    9 F% i9 D* S9 _# M4 C9 I+ f
  939. /*                Nothing                                                                                                                        */
    2 G+ H2 ?8 U1 @( k
  940. /************************************************************************/$ J- h0 N6 L/ Y0 Z
  941. void Wait_Busy()& q% `4 e: Q# n! s6 k; K
  942. {
    3 I% n/ ]% C& B
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */$ }; B2 {1 Q: t( {
  944.                 Read_Status_Register();9 c& |5 A3 F' S# v* C4 l
  945. }. E  z/ ?9 @* x' t

  946. 3 D# v0 K, Y( a4 V; w  U% H. l' a6 N
  947. /************************************************************************/
    0 G5 e4 @8 {6 v0 h, D+ G6 Y* E! u
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    + P/ y; a# D# d) `
  949. /*                                                                                                                                                */
    * }3 Z  C5 G" V; N1 V
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    4 M; `$ d, v7 I3 d
  951. /*                                                                                                                                                */
    * y4 V: R+ }) b6 K' _$ y+ j
  952. /* Input:                                                                                                                                */* o7 P7 `6 S) v* j$ q) ]& ]
  953. /*                None                                                                                                                        */' R' ?. E8 a$ V$ f; N+ L
  954. /*                                                                                                                                                */% L8 y% H: X' g' M3 C$ t9 R* [1 B
  955. /* Returns:                                                                                                                                */
    " r! P7 _* ]1 ]) O. S; J2 ]: y
  956. /*                Nothing                                                                                                                        */
    ; y& r) y6 a0 h* f5 s
  957. /************************************************************************/
    # _3 a) A# w2 A' ~& D3 ~
  958. void Wait_Busy_AAI()
    5 j! N+ [2 K7 d3 w! h
  959. {
      f5 f$ E3 X' z7 A
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */( j  a, }; Y3 r
  961.                 Read_Status_Register();5 `& }+ m, ?1 ^. K
  962. }; Q# s" h; Y& E. R/ O% o

  963. ( k, u9 L6 L* Z/ l, s
  964. /************************************************************************/
    6 @  |" E: K" V7 [  ^1 x/ ^5 ^
  965. /* PROCEDURE: WREN_Check                                                                                                *// b1 z( J" e  i. E0 i
  966. /*                                                                                                                                                */
    2 Z2 F7 V# A6 F' q. {
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    ) ~7 i! e2 v. }! l7 i5 S. L
  968. /*                                                                                                                                                */
    5 R' ^! |& t. n: i
  969. /* Input:                                                                                                                                */
    4 I" H/ @+ [  c$ O3 g7 U5 t2 Q
  970. /*                None                                                                                                                        */
    4 q1 `4 ?+ Z* D+ ^
  971. /*                                                                                                                                                */
    / E3 E! k, |3 C9 {1 [
  972. /* Returns:                                                                                                                                */
    % t/ a6 N9 o8 U1 j& K
  973. /*                Nothing                                                                                                                        */# z4 L8 h5 ^! \' A. u& g
  974. /************************************************************************/, N. z4 T. y3 G1 A3 s+ Z
  975. void WREN_Check(). @3 Q! W6 H# @& j# u" @. F) s
  976. {6 E+ b8 T, H$ @# w" [' V
  977.         unsigned char byte;8 Z. [# h$ P' q! O4 d/ Y. l+ B# g
  978.         byte = Read_Status_Register();        /* read the status register */
    0 n& g8 |1 [& P; E1 H
  979.         if (byte != 0x02)                /* verify that WEL bit is set */- ^: b7 }/ H( ^' X
  980.         {8 M' l5 o+ Y' d' R
  981.                 while(1)
    5 ]% W' [& N/ @. s+ X6 h% V5 M  \, J
  982.                         /* add source code or statements for this file */
    8 Y+ ~$ W; W# Z, C/ R
  983.                         /* to compile                                  */* W" s: ^% S" C  J  w0 A  ]
  984.                         /* i.e. option: insert a display to view error on LED? */
    ; f" h& X; A% t; d( J+ H! g/ g6 J
  985.                  
    , n+ I) ^, T1 i" _9 _
  986.         }
    # u% {, X0 t$ s0 H- h9 Z
  987. }
    , |6 T8 v! Y) u9 {1 N

  988. $ m5 _  ~" _* P  v  i
  989. /************************************************************************/8 \0 k! O4 O& r0 Z
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    % q  x  i# V1 j, x5 q
  991. /*                                                                                                                                                */8 s: J; X- n& y+ W
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */" I* [( E) a. |( P1 D- S8 R& g; N
  993. /*                                                                                                                                                */
    " Q# t8 C; d) m. a$ i6 @' B
  994. /* Input:                                                                                                                                */( O, c- J+ K9 X$ \
  995. /*                None                                                                                                                        */
    ' v( S6 M+ r+ P4 p- B/ Z5 W
  996. /*                                                                                                                                                */
    - ?$ Y0 Q* U4 ?1 F6 S& N# Y
  997. /* Returns:                                                                                                                                */
    / P+ x& w; Y/ D5 M8 {- n
  998. /*                Nothing                                                                                                                        */: C+ {/ p! c6 X6 [# |
  999. /************************************************************************/
    0 @4 ^1 F0 j5 z& [- w/ H
  1000. void WREN_AAI_Check()6 D, S. [$ ?, b+ G' i; ]
  1001. {$ i( a- s8 L% P0 j, _' \
  1002.         unsigned char byte;  L1 j1 U9 q5 Z' {1 M
  1003.         byte = Read_Status_Register();        /* read the status register */
    / u7 _8 ~% f- n  _
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */! g. {( d' S1 z/ o
  1005.         {' `4 k+ S1 S# F1 o# z
  1006.                 while(1)               
    7 I% p5 J: \$ h4 q
  1007.                         /* add source code or statements for this file */! P5 @: Z' p; Y/ ^4 x7 l3 t
  1008.                         /* to compile                                  */6 G- i( Z1 d5 d1 @+ `, k4 w
  1009.                         /* i.e. option: insert a display to view error on LED? */
    + z* w, r/ y' q( l( G+ i2 V6 X- d" ]& n3 C

  1010. ! ?; {( y2 I" G- D9 [/ e
  1011.         }
      i% z& g; A+ ^$ q! p3 J
  1012. }
    4 I# V! }6 n! c
  1013. ' W: ~5 K7 w7 Z$ ^( J2 F
  1014. /************************************************************************/3 o' X' B2 q" y
  1015. /* PROCEDURE: Verify                                                                                                        */
    : F( @- y' d8 C* F
  1016. /*                                                                                                                                                */
    ) J! t1 x# M6 d; M# f: b
  1017. /* This procedure checks to see if the correct byte has be read.                */% ]# L7 P: G; X( x& W4 \7 [
  1018. /*                                                                                                                                                */
    4 ]  f6 x( I' x' N8 U* `' f. U% y0 P
  1019. /* Input:                                                                                                                                */8 o2 m3 A/ _- z+ u# ]/ `* u* z
  1020. /*                byte:                byte read                                                                                        */
    9 P2 L) H' ^% D5 k  m/ V
  1021. /*                cor_byte:        correct_byte that should be read                                        */+ \, {6 ~3 a# m- f  I
  1022. /*                                                                                                                                                */
    5 e' h5 x% l/ `' s) Q
  1023. /* Returns:                                                                                                                                */
    $ K& [# j5 r3 ^2 @, j
  1024. /*                Nothing                                                                                                                        */+ |% I  ?% K- ~
  1025. /************************************************************************/
    - F( P) P$ O* b& E3 _7 }
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
      u5 X) a; \; G/ w  |6 H) k, J
  1027. {9 Y  i( I2 Q. w4 f
  1028.         if (byte != cor_byte)
    ( S$ W* P- y1 j9 O' g. Y3 {
  1029.         {
    8 V! Y: r  r6 H* l5 A( `
  1030.                 while(1)
      L) G9 O2 X3 ^, O. n- A! `
  1031.                         /* add source code or statement for this file */$ I* n& R" M, H( ^1 i' P
  1032.                         /* to compile                                  */  l) `* c. K* X' C+ |
  1033.                         /* i.e. option: insert a display to view error on LED? */
    # [, |' L! M9 Q: b2 o( S7 o+ Q+ D
  1034.                 3 r: l! K0 Z: W+ a- {; C
  1035.         }5 i" H# P4 H, g! Q1 C
  1036. }. Y+ ?+ i/ D7 ^! D* [( V' b

  1037. 9 X6 o9 _( ~" l1 Q# y

  1038. ( I$ E& y6 A+ L7 T1 S
  1039. int main(); S/ s3 Q% @0 J9 K4 M
  1040. {7 p4 v" n% b9 Y1 Y/ ~) u

  1041. / E3 z4 Z& N- c. \2 e/ `
  1042. return 0;
    9 r8 G5 i" D. u
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
/ v7 C6 p7 e: h# \   main()
$ S2 m7 u  y$ T   里面怎么是空的呢?0 Q7 O' @5 a4 p5 ?# R# B
   发一份给我吧5 e1 m! c- C4 [* n
mail:luyijun2005@hotmail.com
! w& T# S9 q3 r7 G咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。% ^) L4 M2 T0 S% w' c; N
% R+ v8 m* N) e& {' @7 n+ u
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
' J4 M  \7 O$ W& }* q, l8 MEC的代码在哪跑,你看DS的说明,每个EC都不同的。
/ R* e. q0 ~3 W0 _- K% nOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?) U5 A' l8 E: H2 o4 H; e. y
上面几个问题是你没看任何东西而白问。
  G6 s! q9 T- P6 q9 a4 X& W2 q
: Z. g, ?6 q" i- e4 ^1 G& o至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
) ]. j  }  V5 o7 d8 y; }1 G* |5 E, G3 n& u1 S" j
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!; F+ {+ \; E( J: p& p! J- Q

4 S) S( i2 B4 S0 I关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
1 O8 M5 |+ O8 m. s& E2 C4 d0 |, E% C5 ~. n" j; v" V  q
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...0 s3 t# G5 y4 X- g
' q) w* ~4 d. j
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样5 x/ \/ n$ i/ r. ?6 @/ J8 ]
似乎要把SPI能support 到最大,这EC chip应该有好卖点% V  ?7 a6 `; l; D( q6 L4 w4 |) R+ w# k- [
BIOS功能要不要强大,也就决定了SPI Flach的大小
8 V! l$ O) k9 z6 h: m我是这么想的~让OEM去决定要挂多大!; H+ |# n* ~$ E5 ^$ U
如果我司有BIOS工程师就好了~哈9 Z/ x6 c8 P! X% M
WPCE775应该算很新的东西,来看它支持到多大?' o- }. Y, N7 S0 k+ b6 O; W8 }

* o& K/ U6 k+ L" m9 T另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
1 C2 u$ Q6 u- h- A其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
% ^" h8 V: ?, ~+ N: J: w
* Q; ]/ L5 J3 q8 R5 E2 k这份driver收下~希望以后有用到& ]3 p+ x& B- A0 T: j/ r3 r) F7 A
谢谢bini大大
8 J! O- @- g! P- V, Y! h+ i6 k% A' P7 O* G
很新很新的新手,如有错误请指正 (准备看第二家的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(); x/ z% i: O5 V; ^  q8 r
{! r% L- m- L) q, m( E
        unsigned char temp = 0;1 E" ?" o/ `' v+ I
        CE_Low();* x; H* l; B7 L& w
    while (temp == 0x00)        /* waste time until not busy */
- Q, M& b" L% I( g, `0 Q# s                temp = SO;
$ z; V* @4 P( w- L' C        CE_High();3 X: H2 x1 j) d/ v
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
) t* F' \- `  r5 {+ v& p{. i( V( @! C7 m; q+ }" C
        
) A2 C; h. }: m        unsigned char i = 0;6 f6 T+ h7 u/ @; U6 p# A
        for (i = 0; i < 8; i++)
& Q- ^6 m  A. O8 ?) c& X% P        {
& D5 p6 b' s9 c1 b9 N                6 N  V6 v8 y6 ?. o+ g/ K
                if ((out & 0x80) == 0x80)        /* check if MSB is high */2 P3 L  O4 \$ x( f' ?; z5 H
                        SI = 1;
5 a% v* d+ h, F  A- q% z5 R% c                else
8 r# |9 z6 g5 x$ g% X/ a* C                        SI = 0;                                /* if not, set to low */) S5 m) n, R. W3 h- n# P
问              SCK = 1;                                /* toggle clock high */) f2 ^/ j, F& W2 j
   题            out = (out << 1);                /* shift 1 place for next bit *// G/ Y4 J: ]4 B
                SCK = 0;                                /* toggle clock low */
7 v( @$ J* H) q$ `: j        }
+ ~. @/ f# W% o* }) E, @, l}
. z( z9 ~  X! ~9 M: s# t: _* f 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-3-5 14:14 , Processed in 2.365729 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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