找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54765|回复: 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
    2 `+ D4 n6 g% e( g' Z( l

  2. . z" [# k6 C8 n# r/ |5 j
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    1 G$ e: {4 h+ R+ i1 N  T3 W

  4. 5 P8 v% Q# ^% [; }1 `) |! M
  5. November 4th, 2005, Rev. 1.0
    " w) F, s! n% ~' N( g& ~
  6. ' l; o1 c" k7 O6 H/ E+ k
  7. ABOUT THE SOFTWARE# B& `1 W9 J0 U' I
  8. This application note provides software driver examples for SST25VF080B,, R8 l: t, I$ A! Z; \0 Q9 |4 t
  9. Serial Flash. Extensive comments are included in each routine to describe + ]2 O2 p, S, X9 g$ o7 L
  10. the function of each routine.  The interface coding uses polling method
    5 V3 F7 J5 p3 c. s5 R
  11. rather than the SPI protocol to interface with these serial devices.  The& W" c" e7 \8 x) d
  12. functions are differentiated below in terms of the communication protocols
    5 j" s4 ~! s0 Q8 r6 j
  13. (uses Mode 0) and specific device operation instructions. This code has been
    ! u, j8 N. v$ g, o5 C2 }
  14. designed to compile using the Keil compiler.$ o7 {# ]" S6 t

  15. * z, w; `5 @- j" X
  16. ! m2 ~0 J' x" h; Q" A5 l8 f/ S7 m
  17. ABOUT THE SST25VF080B! M1 r, P; O4 F2 j; Z
  18. 6 z: d! D( p: ]
  19. Companion product datasheets for the SST25VF080B should be reviewed in # Y3 {7 `9 O+ q# z$ H- d" ]7 E
  20. conjunction with this application note for a complete understanding
    4 t- _3 n1 ^2 s  ?
  21. of the device.
    . C9 r8 U* U+ l

  22. ; q+ P# |$ Y3 y/ z
  23. ) W+ E8 G) |* m) ~! G2 u
  24. Device Communication Protocol(pinout related) functions:& I$ ]* a: F! q. `8 w
  25. $ u' P$ I7 g$ S( l; W* R# o
  26. Functions                                    Function
    * F$ I  o6 C  R. r4 s3 a
  27. ------------------------------------------------------------------
    + G- O0 S) `4 k
  28. init                                        Initializes clock to set up mode 0.
    2 B1 V" l( }3 E+ c4 x. M
  29. Send_Byte                                Sends one byte using SI pin to send and
    ( A9 I3 T2 [6 y3 D  H
  30.                                                 shift out 1-bit per clock rising edge6 |. e: R% I2 I- x2 R
  31. Get_Byte                                Receives one byte using SO pin to receive and shift ; @$ t. W3 ~: t8 S) F& e" l
  32.                                                 in 1-bit per clock falling edge
    # o) L4 c1 x% @; h( s
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming0 o; l2 ?/ R' _3 W' S% {
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    4 q) Z4 N( f8 [+ h: ~- I: K, O: t
  35. CE_Low                                        Clears Chip Enable of the serial flash to low& e% v5 t# Z. v. f! T$ h' }+ ]
  36. Hold_Low                                Clears Hold pin to make serial flash hold* M$ E/ ]0 ~4 t: n1 j- @+ v9 m1 D% C
  37. Unhold                                        Unholds the serial flash
      \% e6 n' T6 D
  38. WP_Low                                        Clears WP pin to make serial flash write protected. I- {' W  e: [, j2 @% C- B
  39. UnWP                                        Disables write protection pin
    0 J4 x# V9 n1 p/ t( L

  40. 9 L: o3 V4 i; h; F; z
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    ( }8 Q# j: |! G
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    + t& q$ k6 ^9 ^% `1 G
  43. software which should reflect your hardware interfaced.          
    * s0 F% D/ p9 k/ Z* i0 D

  44. & b- u0 a" {. Y( l

  45. 2 Q0 Y' T- }& ^- o: A7 C
  46. Device Operation Instruction functions:  E8 R% b9 t: N, l- P, T- Q

  47. 4 r. ], I8 x* S7 ?5 Z- ~6 A
  48. Functions                                    Function6 \9 _4 p3 J9 b5 @3 Y' U
  49. ------------------------------------------------------------------7 w+ B. o. o+ c6 f; O7 u: G. m: }
  50. Read_Status_Register        Reads the status register of the serial flash# ]* k3 C3 n; |- T7 q
  51. EWSR                                        Enables the Write Status Register
    2 R2 M5 [# W6 a' }" s
  52. WRSR                                        Performs a write to the status register* ], p: W/ \8 ?2 |8 s: E
  53. WREN                                        Write enables the serial flash# f' K; \/ n; @, J
  54. WRDI                                        Write disables the serial flash
    3 d) P& l+ U& C; T
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming; R& t+ f1 q4 n
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming  J; X: ~, T' {! t
  57. Read_ID                                        Reads the manufacturer ID and device ID
    , [. @1 L* u- m5 r
  58. Jedec_ID_Read                        Reads the Jedec ID+ E  {' r: X6 b  C* y9 V$ i
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)( C5 l8 M5 t# b% q0 m0 k( g
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    1 J- ?) G  t# ]/ {; L
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)7 L0 @# j8 P8 X, D
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)  q8 F0 L/ ]- E/ u( }$ T
  63. Byte_Program                        Program one byte to the serial flash
    ) z  ^" a, A1 A
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    ! J; c$ ?2 G8 i- V
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation+ X, X4 Z) G& _5 G  w
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    8 R: ^3 p8 Z$ c- F
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    $ Y9 `/ r0 i# O; u1 Q
  68. Chip_Erase                                Erases entire serial flash; o% }5 C$ Y, C. D* Z' c
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash! K6 r* n6 L6 L% A' h: y& x: Y5 O
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    2 J  F; T4 {0 e) r& z9 [
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    : C+ t1 n3 `7 ~& D' g- w, @
  72. Wait_Busy                                Polls status register until busy bit is low4 S3 T  t( Y) T' q
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    8 @& C- x- i" t
  74. WREN_Check                                Checks to see if WEL is set
    % V0 F* G8 k5 I6 p) K
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set" i2 Q. z+ S! L

  76. ( f4 A+ C# c/ `  E* L6 ]( p; y

  77. 1 d; \; ^1 J. O9 w6 U# M3 L  `  {2 i
  78. 8 _( X8 m; j9 y# }
  79.                                                                      + x4 v$ A" L7 [1 J; u7 ~' X! j
  80. "C" LANGUAGE DRIVERS & b" F4 @5 ]$ k+ O

  81. 0 y2 f+ ?! q3 ]- J
  82. /********************************************************************/; Z( v( J& V4 w# J* |) i, \
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */5 f! B. `& f/ |
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */* [! i& D  x( Q. U
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    3 A% Z" C5 x/ {7 m) z
  86. /*                                                                  */
    $ y% W! s" Q% d( ?0 R& m* [; Q3 u
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
      m5 X0 {! c7 I! n% ~9 q$ Z
  88. /*                                                                  */
    3 m# [0 @  A- H3 H8 h
  89. /*                                                                                                                                        */
    " S6 D5 B3 O# x& G5 ]3 e$ }% I7 r+ h
  90. /********************************************************************/
    / v: F# ]) Z1 F: E9 _

  91. : W2 s  a: j6 Q3 W: I; r+ w5 D
  92. #include <stdio.h>
    2 [* o* m2 o/ G: D3 S
  93. #include <stdlib.h>  [( T9 s8 n  F6 g7 b

  94. 2 b1 J3 B: [8 m$ f4 m- ]! R+ [
  95. /* Function Prototypes */
    $ w9 B8 C' E; ]2 ^4 b+ w$ ]9 S

  96. # i, x/ z$ B. ^- j+ j: G! C
  97. void init();
    4 K0 Z8 e! Y) g$ m% k
  98. void Send_Byte(unsigned char out);
    % q7 h+ b1 k% G, S
  99. unsigned char Get_Byte();' h! L0 U8 E0 O$ S; F! C' _+ x+ n
  100. void Poll_SO();
    ! X4 N- _0 L9 `, B9 g% d6 \/ h
  101. void CE_High();
    * n; a+ v. X5 B  x6 P: Z; ~7 B& k
  102. void CE_Low();
    9 K: V: f$ W$ s" L$ \- t
  103. void Hold_Low();+ F2 z2 ~- S8 W
  104. void Unhold();
    " B+ w/ _) e; n' M+ I  B; T
  105. void WP_Low();
    ' l: c/ y2 h7 U3 a  l
  106. void UnWP();; f7 H2 r$ d' V+ E1 U2 L
  107. unsigned char Read_Status_Register();) s* u) R3 m8 N. |! Q
  108. void EWSR();5 I6 ~0 _4 e" e1 k
  109. void WRSR(byte);
    0 P" V6 |- [! g  ]5 _
  110. void WREN();
    % }* n1 T3 t" l4 _0 [- [3 Q
  111. void WRDI();) E3 `$ i$ O' g- {
  112. void EBSY();
    ' N& e% }6 T7 j5 W1 h; v
  113. void DBSY();
    . s$ U6 z. Q" a3 w2 k. m2 y
  114. unsigned char Read_ID(ID_addr);& C& d. J9 R6 ~
  115. unsigned long Jedec_ID_Read();   ]  Q0 h% y; ^1 h+ c# R3 G
  116. unsigned char Read(unsigned long Dst);8 \" U& w, _+ _0 K& m$ z
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);8 o) M. s5 V: r4 ]
  118. unsigned char HighSpeed_Read(unsigned long Dst); / u. e( n3 E: q: }% U5 G
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    9 |! _' ]# q" T6 `2 b9 J9 [1 d( |
  120. void Byte_Program(unsigned long Dst, unsigned char byte);8 Q4 m' T) M, C6 u5 ~. J
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    . H2 K$ `3 T+ E
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);  j, ^. Y% K" I( T
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    4 R1 o* W' i" R  M$ v$ D
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);- |2 f( c0 c" B( A4 Z8 j' s& f
  125. void Chip_Erase();
    * X7 f2 z2 G8 V* Y6 P, l, C+ I, J
  126. void Sector_Erase(unsigned long Dst);: J5 @/ @6 X+ L' d8 g9 m5 C4 r
  127. void Block_Erase_32K(unsigned long Dst);$ r4 b; e8 t- t4 r
  128. void Block_Erase_64K(unsigned long Dst);" U- `+ G9 n8 N+ g
  129. void Wait_Busy();
    , p7 D) r9 ?6 d8 ?9 ?
  130. void Wait_Busy_AAI();
    3 _3 V% a- i* I, _
  131. void WREN_Check();6 S9 I! D  y0 u& }: d! P
  132. void WREN_AAI_Check();- L% p; _% ]% e

  133. # @! ]; Z3 Q" l/ O5 U
  134. void Verify(unsigned char byte, unsigned char cor_byte);+ m* l; c& V1 M) v
  135. ' t+ u# g' ~$ [
  136. unsigned char idata upper_128[128];                /* global array to store read data */& U1 l" F% E4 k- H1 m% k# G, W
  137.                                                                                 /* to upper RAM area from 80H - FFH */. s& {* u6 I, Z& _0 `; c, q
  138. # a% T/ S5 y" u% H$ R$ G! k
  139. /************************************************************************/
    . Z1 h( K! y! Z7 x! a
  140. /* PROCEDURE: init                                                                                                                */
    & d: |9 U( j0 ~, W
  141. /*                                                                                                                                                */
    , l, t: m& u% r7 V' H
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    $ `# E3 s5 v  L" ^$ h
  143. /* setting up mode 0.                                                                                                        */# p% q, Z- m0 }; s4 K. i
  144. /*                                                                                                                                                */
    * O: V; i# w, ^5 ?; W
  145. /* Input:                                                                                                                                */
    & H: j! {3 `. v' a
  146. /*                None                                                                                                                        */
    5 S8 R; x" i; L8 ?* e+ ]8 d
  147. /*                                                                                                                                                */+ @' z# i. c) W% @  q
  148. /* Output:                                                                                                                                */" ?) B  G0 n/ t# ?
  149. /*                SCK                                                                                                                                */+ }$ @1 E& |! I9 o1 x% ^
  150. /************************************************************************/
    ) F$ u+ P3 @: M3 j" w0 s' O3 q- A5 @
  151. void init()
    ; t) ]# ]' z5 T! u$ o5 D6 D
  152. {/ r4 {6 r; V+ O2 a! e9 Y
  153.         SCK = 0;        /* set clock to low initial state */! y8 S' Y! K) n' W. p
  154. }& ^$ x' D9 g# J, p8 ?4 R
  155. / ~8 w# I" v# j) F$ U" g
  156. /************************************************************************/
    . q! I8 X- F1 K5 ^9 e
  157. /* PROCEDURE: Send_Byte                                                                                                        */+ v% Q5 A. q; o* ^8 U( ~
  158. /*                                                                                                                                                */
    0 |* T4 @& H7 O* l$ ?+ M! q
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */$ D  Q$ |, L5 c" J( x" U
  160. /* edge on the the SI pin(LSB 1st).                                                                                */( \* g1 G: p% |/ y9 {( W2 ^
  161. /*                                                                                                                                                */6 o# N" _  G' j. j$ B
  162. /* Input:                                                                                                                                */
    ' k) b4 [. w! Q9 l( D8 j
  163. /*                out                                                                                                                                */
    3 _. w* Y0 O# B% y2 V
  164. /*                                                                                                                                                */
    7 v1 u$ x# h; w+ `, P: p# R
  165. /* Output:                                                                                                                                *// e2 D5 {- d3 v6 e1 V' R1 n6 o
  166. /*                SI                                                                                                                                */% ?, K# j* E/ f; p1 }  ^
  167. /************************************************************************/1 c# ]4 e: [6 q0 J) A" z" i1 x/ S
  168. void Send_Byte(unsigned char out)
    0 ^( x6 h: n% H& R
  169. {
      ?) a5 h  ~1 n$ G5 j
  170.         # Q7 J. r' }5 K
  171.         unsigned char i = 0;
    ' b8 l6 j. K- m4 o
  172.         for (i = 0; i < 8; i++). T8 U+ ?# ?6 q% u5 e6 f7 R
  173.         {
    6 ~9 Z; y  \: u- s: z  W
  174.                 & ]- {) j! N. [0 f6 ^- @
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */3 f: w4 Z/ o# X4 y7 e# Q
  176.                         SI = 1;& S0 H0 y; R2 h
  177.                 else
      h6 b( W/ T; g2 _9 R: B3 E
  178.                         SI = 0;                                /* if not, set to low */
    1 \  b! B& E* _2 ^* _- [; k& l
  179.                 SCK = 1;                                /* toggle clock high */
    1 L' p& V* r8 b
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    7 j" L7 Y' n, [2 s
  181.                 SCK = 0;                                /* toggle clock low */  `5 v% m3 N) u  U% ^/ z, @  J
  182.         }
    ! D0 J, R4 y1 {8 W- m9 A1 X
  183. }9 Z9 j& _$ A  D$ N) i, X$ n
  184. 4 {$ j9 a) p" H' U; ^
  185. /************************************************************************/
    7 c3 O( u! x3 ~0 i) M, L9 a
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    - r4 ]+ ?$ U- c" w6 X, [! ~; H
  187. /*                                                                                                                                                */
    # q2 R6 J! N) h" E, ^
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */% V& G1 U! R8 n, Y3 E% A
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    1 s9 w; }4 Y" O& @8 I, ~
  190. /*                                                                                                                                                */8 O" A. p, A$ i8 Y: W/ _$ V
  191. /* Input:                                                                                                                                *// e! q6 `- c+ S6 n2 j! [; Z) G
  192. /*                SO                                                                                                                                */
    7 X; x# W3 G4 Z8 s
  193. /*                                                                                                                                                */
    0 C5 U* v" j5 w/ c/ ~$ V
  194. /* Output:                                                                                                                                */
    1 K5 f- n' E' G8 p. z
  195. /*                None                                                                                                                        */
    - e& D- V. U9 j) L$ j& F; x. r
  196. /************************************************************************/1 B( {1 M, e2 j( C( m) M( W
  197. unsigned char Get_Byte()4 d- I8 _( q- ]- L, u) Q
  198. {) t5 A+ T! V: a
  199.         unsigned char i = 0, in = 0, temp = 0;8 A) U" p$ M, f. N4 b, s+ D
  200.         for (i = 0; i < 8; i++)  i- P) P$ p! U+ z  ~# E  k
  201.         {8 V$ N  H8 b* m" J" [5 _' j
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */# P# w) o0 w) b
  203.                 temp = SO;                        /* save input */
    5 @& W2 e8 N; z5 v9 A4 N/ `) `
  204.                 SCK = 1;                        /* toggle clock high */9 m/ l$ o" ^* t
  205.                 if (temp == 1)                        /* check to see if bit is high */
    7 ~0 c2 E. _0 S/ @7 X
  206.                         in = in | 0x01;                /* if high, make bit high */- @& s# Y) [; S2 Z
  207. 5 a' ~- C% Z1 ^" }# @2 i( U! P+ E
  208.                 SCK = 0;                        /* toggle clock low */* z  A' S; e* J' S8 s( t
  209. / r6 n2 b- A- `, U- a2 x9 Z
  210.         }
    5 n* P9 \0 l8 T# H8 c/ A8 {
  211.         return in;6 }/ r6 O# p+ S( }8 C, t
  212. }/ g$ a( M9 v9 k
  213. 2 j: n) v5 ^% F: b2 m
  214. /************************************************************************/
    ( [2 O# k2 Y9 H( C  R; g" L9 s
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    - Q! `; k( G6 Y" X8 J* ~  {) G
  216. /*                                                                                                                                                */
    / ?3 l! `  B; c! W3 d. o4 n! C
  217. /* This procedure polls for the SO line during AAI programming                  */
    ( n& m: l, U) e! f( \
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    6 ?" e  h' p$ u8 I! ]
  219. /* is completed                                                                                                                        */
    ( a! B& D, w4 {! g( V; V9 n( F
  220. /*                                                                                                                                                */' L1 c% k8 |0 N4 g7 z
  221. /* Input:                                                                                                                                */
    ) m0 }" _  ~1 S* F
  222. /*                SO                                                                                                                                */9 ~3 D/ z7 K& b
  223. /*                                                                                                                                                */0 j2 Q( q$ F& D% L) R
  224. /* Output:                                                                                                                                */
    % v- I; j( j5 V) J+ H
  225. /*                None                                                                                                                        */. L: J# u/ h( P
  226. /************************************************************************/' t5 j3 K; U5 b) r2 I
  227. void Poll_SO()
    5 O& O5 N- t6 ]6 M
  228. {
    # a5 ^" e* b' B" K; X
  229.         unsigned char temp = 0;: L8 B# j0 H  \) x% X
  230.         CE_Low();" \9 i" k/ F- G9 z" I# [
  231.     while (temp == 0x00)        /* waste time until not busy */
    . J  a: F9 h% h2 _* K! K3 o
  232.                 temp = SO;) k# S- z$ e% D: Q( L+ {
  233.         CE_High();
    $ [" R( o- H$ p! Y. V$ ^
  234. }. S) G& u3 S! X  n. c; s

  235. 9 X( w; B* R. f. x
  236. /************************************************************************/
    3 C# ~3 N# \! e4 Y& K# D
  237. /* PROCEDURE: CE_High                                                                                                        */
    5 t6 a/ o/ f7 w1 @: K' `/ |. P& [
  238. /*                                                                                                                                                */
    5 i6 ^, p5 K3 w1 ~
  239. /* This procedure set CE = High.                                                                                */
    3 f! F8 t# v- w8 U- d6 w' n( Q9 J( A0 f
  240. /*                                                                                                                                                */
    4 \/ I2 I+ a& [/ e
  241. /* Input:                                                                                                                                */$ _, Z" S6 U7 c1 T" r, o/ U
  242. /*                None                                                                                                                        */
      n3 H- Q1 G: ~+ V. W/ I* [
  243. /*                                                                                                                                                */5 ~5 H( q/ N' M7 t
  244. /* Output:                                                                                                                                */& b% [9 b$ H( m  a0 [8 }# b5 G
  245. /*                CE                                                                                                                                */
    - ^* w( c, y6 }+ J* _0 T' L
  246. /*                                                                                                                                                */
      }: l- G0 J$ b+ J# a. t; N& E# W
  247. /************************************************************************/: `( n) y5 \, Z- H4 d" b  e
  248. void CE_High() 6 }: B2 X& q9 }4 f5 x2 P
  249. {
    ' f2 D7 y! n# e
  250.         CE = 1;                                /* set CE high */( P/ \: n( Q3 |+ _9 g
  251. }6 |' J9 L- A( h7 y6 h

  252. 7 [  }7 i2 @  E1 `  g
  253. /************************************************************************/
    ' V# W% Z( o, A  ]- l. B; W
  254. /* PROCEDURE: CE_Low                                                                                                        */: R& g7 D# J, G
  255. /*                                                                                                                                                */
    2 z" r6 ?  F2 x, X, o* H
  256. /* This procedure drives the CE of the device to low.                                          */3 G2 m/ _0 P% d3 p, f6 X
  257. /*                                                                                                                                                */0 t5 B1 B" s' H  a1 u
  258. /* Input:                                                                                                                                */8 z  w: f9 }! J7 j# J, M
  259. /*                None                                                                                                                        */6 K! v) p' `# g* _' z# j( \% U
  260. /*                                                                                                                                                */
    ! J( |" {' I4 R' W% t/ g
  261. /* Output:                                                                                                                                */
    ' B( `' @( I1 w
  262. /*                CE                                                                                                                                */
    % T0 V; w1 [5 j, P2 k" R
  263. /*                                                                                                                                                */
    5 d6 S# y0 X( z; P! ~, v1 z3 P  T
  264. /************************************************************************// Y! \, O2 ?2 _0 L  Z5 q* e
  265. void CE_Low() ; x6 W1 U7 c% Q
  266. {        $ x( u+ m8 h/ M
  267.         CE = 0;                                /* clear CE low *// P2 x8 ?, f5 N) D0 e7 q2 C) `
  268. }3 ?& q8 Q7 c- ]9 \
  269. & Y1 r& z3 \( _6 b; }1 M
  270. /************************************************************************/
    8 x: b6 V4 ]  X+ F) [: s
  271. /* PROCEDURE: Hold()                                                                                                        */$ j! Y1 ^  ]: N1 X0 M6 U
  272. /*                                                                                                                                                */
    , g5 o& N- M4 W' m4 f- [
  273. /* This procedure clears the Hold pin to low.                                                        */2 X& r7 K2 u: W( K- R  F
  274. /*                                                                                                                                                */
    - B* f2 J- c0 Q; B, b$ A& d- _' I3 r
  275. /* Input:                                                                                                                                */* _/ v2 D0 E, p5 f  {) W
  276. /*                None                                                                                                                        */
    0 Z% _2 v# \. J' L
  277. /*                                                                                                                                                */
    8 s1 N2 e8 _9 k0 `. a
  278. /* Output:                                                                                                                                */6 D) }$ A6 P% w/ E7 O
  279. /*                Hold                                                                                                                        */& k0 |) h  s% F
  280. /************************************************************************/. H9 [$ g$ x* W! [0 x
  281. void Hold_Low()- T0 S+ z0 A+ n2 j" s/ X) M
  282. {4 ?. Y3 s! @$ V; A9 \$ X
  283.         Hold = 0;                        /* clear Hold pin */
    3 r, J9 }/ i4 B. p' r$ H* a: Z  h' e
  284. }
    , ~: P2 e3 N, e( h: k& E7 ~. T+ [

  285. 1 O& ^2 Z& @$ q6 ]8 c+ K% y
  286. /************************************************************************/$ m9 w  s9 T; D
  287. /* PROCEDURE: Unhold()                                                                                                        */
    $ @9 j6 z5 Y' w: G  K+ M6 j
  288. /*                                                                                                                                                */
    1 `, I$ h1 i; T/ A7 K3 d
  289. /* This procedure sets the Hold pin to high.                                                        */
    & ^1 Q& x7 a3 y. N, z  R
  290. /*                                                                                                                                                */0 `! o; F) ~2 l) \
  291. /* Input:                                                                                                                                */
    * v; P  O3 n. z# S
  292. /*                None                                                                                                                        */- X9 K& q4 @& K/ K$ [. C# }
  293. /*                                                                                                                                                */
    - r' J, ?+ x, O- ?( M4 y# |
  294. /* Output:                                                                                                                                */% @: L, i& |* B$ G( G# V* z5 H9 \
  295. /*                Hold                                                                                                                        */1 c7 T( o( O! V3 W8 R% b0 @( L
  296. /************************************************************************/
    6 Q" _. b. L. u( W7 k1 _
  297. void Unhold()
    3 L, I( @% y* ?
  298. {
    : f) w) A+ B8 L, U8 F! E9 _
  299.         Hold = 1;                        /* set Hold pin */
    + f% q9 e& k5 J; X  P" Y/ c( e
  300. }
    ( @- R, X: b1 v8 \9 q

  301. + }1 W! v: v2 P( z
  302. /************************************************************************/
    3 W/ H  L5 f: }, {# A
  303. /* PROCEDURE: WP()                                                                                                                */7 V9 f) E$ o+ I4 c# w
  304. /*                                                                                                                                                */) A% e' ?+ {4 z+ B* R2 e
  305. /* This procedure clears the WP pin to low.                                                                */9 E3 f1 I4 ^7 h8 `, Y
  306. /*                                                                                                                                                */
    & q) j" ?' M9 T4 s1 s3 P( r- S
  307. /* Input:                                                                                                                                */3 ~4 H$ ?( k! P/ N0 b8 g2 m" u
  308. /*                None                                                                                                                        */0 _) _: J0 |; r* X' T4 N, l
  309. /*                                                                                                                                                */
    3 z3 |+ _6 d8 L/ X/ ~1 |
  310. /* Output:                                                                                                                                */
    % v3 d# p2 [. D- ?  u9 G: O1 W$ B1 J
  311. /*                WP                                                                                                                                */
    1 h" B& |; K5 T" U! E
  312. /************************************************************************/4 ^# h/ `3 t, R9 {' z- E
  313. void WP_Low()
    7 [4 `( S3 h' C9 M- d
  314. {
    6 S6 s$ k. Z! r# v: I' q) c2 e+ r
  315.         WP = 0;                                /* clear WP pin */# e* J% E' b' ~9 P
  316. }
    2 w  a: s. k! d) B4 O, f
  317. ; [4 L  w/ m; k6 n" J) z/ A  h* p
  318. /************************************************************************/
    : y6 X9 E! @* i; |0 t
  319. /* PROCEDURE: UnWP()                                                                                                        */, I9 l6 l/ v: z1 B  E
  320. /*                                                                                                                                                *// l: L) H/ Q' K( R5 [
  321. /* This procedure sets the WP pin to high.                                                                */
      ]1 W- X( Q; C/ R4 v
  322. /*                                                                                                                                                *// i6 e& {- q* Z
  323. /* Input:                                                                                                                                */
    ' M7 K: j/ v5 G1 H+ q5 `) a
  324. /*                None                                                                                                                        */  T/ x: ~6 v$ Y: C0 _0 j  M
  325. /*                                                                                                                                                */
    7 \# E5 U+ Q' Y. l' g, e+ T
  326. /* Output:                                                                                                                                *// \4 o  G2 A% p0 |& z* {2 @7 z
  327. /*                WP                                                                                                                                */
    : S+ h' i: W- }5 w* ?, f8 n7 T0 B
  328. /************************************************************************/9 P" o+ I( M9 j: }( S, Q
  329. void UnWP()/ o( t' X  Z3 O& E
  330. {
    ' ~5 L2 C* A5 K  S
  331.         WP = 1;                                /* set WP pin */
    - V  q( G6 m; h6 D
  332. }7 X1 S/ F# |. T0 x& e' d' z# D8 E
  333. ! q! H9 H' c7 n4 l% D! E7 d
  334. /************************************************************************/
    - l5 G! l' ~. ^" y2 }
  335. /* PROCEDURE: Read_Status_Register                                                                                */9 P, l% \5 V% d9 \: z9 K$ K
  336. /*                                                                                                                                                */9 K+ q5 R  t& K" u0 {0 C5 L# }
  337. /* This procedure read the status register and returns the byte.                */
    * l! [% f/ I8 ^& l2 ]5 n8 l) j
  338. /*                                                                                                                                                */
    7 D9 I2 x  Q' z+ j8 ]
  339. /* Input:                                                                                                                                */% ]' P# r8 P# ^3 Y- I* h! q
  340. /*                None                                                                                                                        */* m- i; f$ r( Z& i+ f5 r
  341. /*                                                                                                                                                */( }( v& J2 c$ t
  342. /* Returns:                                                                                                                                */
    ; k; a$ n! p( E4 M7 E  `
  343. /*                byte                                                                                                                        */
    ; A& f4 O) S  C% c
  344. /************************************************************************/
    3 D5 O9 [# E- r- k- }+ m$ g% p1 o0 n
  345. unsigned char Read_Status_Register()& R- H9 r/ G& r" h, p, r
  346. {
    # n) Z( ]1 r' z0 ]& r
  347.         unsigned char byte = 0;4 ^0 b% I8 H  f2 C" x  S/ `6 I
  348.         CE_Low();                                /* enable device */! H+ M6 a4 L. [3 G3 l; `4 b3 F
  349.         Send_Byte(0x05);                /* send RDSR command */
    , Y' _. J7 }/ c' }( A& \8 \
  350.         byte = Get_Byte();                /* receive byte */: w3 M1 I; U4 n( j( b- b
  351.         CE_High();                                /* disable device */
    & y) C+ M5 [9 T2 v+ n5 W
  352.         return byte;
    8 W, @) t" u: u& {+ z
  353. }
    5 Z7 N( c. L) D- [+ r+ Y# y# l1 w& L
  354. 1 `" {4 r3 ~6 m$ M
  355. /************************************************************************/
    % C* ], b; u& I& y2 |
  356. /* PROCEDURE: EWSR                                                                                                                */" L# {% [- c& A7 A
  357. /*                                                                                                                                                */( k% x% `4 {# }9 j( T
  358. /* This procedure Enables Write Status Register.                                                  */9 D2 \1 v0 {$ V9 I" r
  359. /*                                                                                                                                                */
    0 R; Q1 L# a+ y) N+ X. b+ f
  360. /* Input:                                                                                                                                */
    6 V# u1 H7 f# y+ O
  361. /*                None                                                                                                                        */
    0 f6 ?0 O$ ]8 E0 B" h
  362. /*                                                                                                                                                */
    5 [8 b- s; \( q8 }9 e& W
  363. /* Returns:                                                                                                                                */9 [. M' I7 B8 B  B. D$ n( e4 M) s( Z
  364. /*                Nothing                                                                                                                        */
    # I5 `' v% a+ M: H7 w
  365. /************************************************************************/2 {' F5 _* w& S* n0 ?5 n
  366. void EWSR()
    / V3 U: b, d- I. I6 Z
  367. {
    , A8 F# g+ a4 j
  368.         CE_Low();                                /* enable device */* ]: N$ {( W, e  }
  369.         Send_Byte(0x50);                /* enable writing to the status register */* X7 p) y$ g5 s( @; z! N. q
  370.         CE_High();                                /* disable device */! C1 X* X9 i( }% ~2 J
  371. }: Z& }. {9 X* N- b0 y$ [  a

  372. & H6 j0 k  d% K, P
  373. /************************************************************************/
    % Q- J5 x! S) i+ q3 U
  374. /* PROCEDURE: WRSR                                                                                                                */2 _' @6 B3 \# @; W3 P: }: D( O
  375. /*                                                                                                                                                */
    $ i  L- |: M, e0 \
  376. /* This procedure writes a byte to the Status Register.                                        */
    # B" ]4 d" c, M. C4 C/ ^5 y, L
  377. /*                                                                                                                                                */
    5 l, `1 k, E' r' f7 u! y
  378. /* Input:                                                                                                                                */
    ( e0 }# f0 q/ H
  379. /*                byte                                                                                                                        */3 S+ U' }' }% Q8 u. ~
  380. /*                                                                                                                                                */' [# [+ Y6 V7 ?9 N+ S
  381. /* Returns:                                                                                                                                */
    . o2 B% M, e  V  l- H( m% ~% |
  382. /*                Nothing                                                                                                                        */  i# L/ ?# O& w! X+ _
  383. /************************************************************************/
    % E. D2 S" d( g0 L6 }1 X
  384. void WRSR(byte)
    $ |, W% ]: ^; `  ?* x9 e. `% h6 c
  385. {
    / a( p( k2 |: |
  386.         CE_Low();                                /* enable device */3 p% J* G* {. R- r% B- i" }
  387.         Send_Byte(0x01);                /* select write to status register */
    ! r( j! ^6 @. ]' F  k
  388.         Send_Byte(byte);                /* data that will change the status of BPx % z" V- r3 A- Y) c! U
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */! `$ p0 _6 O* ]9 G* V
  390.         CE_High();                                /* disable the device */
      j8 a. {  C% y
  391. }! ~* ^8 k' L) u- c* g

  392. , @0 y; y! a7 f7 p5 q# x! \4 R
  393. /************************************************************************/( m' t5 C- w! ^4 s- t& i
  394. /* PROCEDURE: WREN                                                                                                                */
    % o$ L  ]! r$ D' y% F
  395. /*                                                                                                                                                */* J" A5 A, n1 X, t2 p9 k
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    ( J( \* Y3 y4 r# w1 J' ?' x
  397. /* to Enables Write Status Register.                                                                        */6 b, X5 ?, p6 U6 P  J: O
  398. /*                                                                                                                                                */4 j2 i# _1 n! H
  399. /* Input:                                                                                                                                */3 F; {5 P: R( F$ m, C4 c
  400. /*                None                                                                                                                        */
    2 C1 ?, B4 e! r! X  _6 n4 s
  401. /*                                                                                                                                                */
    2 l; b' T8 F0 [# [% E+ d5 e
  402. /* Returns:                                                                                                                                */$ \! U5 U& j( e$ k& h# P
  403. /*                Nothing                                                                                                                        */
    ; Z* c+ g2 Y5 L  O7 X- ]
  404. /************************************************************************/
    # l! O6 x- I8 i+ S' U& }# x! h7 ]
  405. void WREN()
    8 K; z' \; B! t. |( N
  406. {
    & \' w/ J5 @: H, Z. U& y/ q
  407.         CE_Low();                                /* enable device */
    + [4 ~: ?: y0 h( ^
  408.         Send_Byte(0x06);                /* send WREN command */: D" q9 F1 J0 g+ v/ O
  409.         CE_High();                                /* disable device */$ W1 X5 E7 a  C# h
  410. }
    ' e6 E( R" ]7 Q
  411. , Z) R7 z* {  F! G; a
  412. /************************************************************************/7 \8 p4 k. O' ]# P6 G8 T
  413. /* PROCEDURE: WRDI                                                                                                                */3 u) ]# [' N8 I7 I* w
  414. /*                                                                                                                                                */. T( ?) S4 \5 D* S4 l
  415. /* This procedure disables the Write Enable Latch.                                                */
      G! B$ `5 W6 X% {$ S
  416. /*                                                                                                                                                */
      Q/ F6 M2 X0 e
  417. /* Input:                                                                                                                                */
    . ~3 g9 z/ x' t
  418. /*                None                                                                                                                        */4 o5 w" _. @, z7 n& j5 X
  419. /*                                                                                                                                                */
    # q0 O. C# }* j0 q8 G! N7 ]* p" {
  420. /* Returns:                                                                                                                                */  Q# ~# [8 Y9 B) _" c# B0 ^
  421. /*                Nothing                                                                                                                        */
    ! i# S' J& ~7 ]6 _3 F1 a) U+ h3 J
  422. /************************************************************************/. v! W- W! a- a
  423. void WRDI()
    ' _' _% `" `7 ?$ i/ `' d
  424. {
    2 i; W/ N: u+ L# P/ j% `
  425.         CE_Low();                                /* enable device */
    - y  T5 x8 Z+ l, _+ d6 U8 Q
  426.         Send_Byte(0x04);                /* send WRDI command */
    0 V% S+ ~& J/ N, G/ z
  427.         CE_High();                                /* disable device */
    1 u, B5 E* P; w2 o$ b( A
  428. }# N% ~' t# d; ?3 Q2 u
  429. 9 h# |# G1 X4 I( G
  430. /************************************************************************/4 x2 C, \) S+ Y" c- K
  431. /* PROCEDURE: EBSY                                                                                                                */
    ' b& ^+ Y6 H+ e8 Z- s4 _
  432. /*                                                                                                                                                */
    $ T" u; d9 S0 e7 k
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */  {$ e! F1 z5 H0 k! j) S+ j
  434. /* programming.                                                                                                                        */
    4 V) z* Z% X3 E9 N- P
  435. /*                                                                                                                                                */  t6 `. L# y6 ^& D) F% K1 E: f* m
  436. /* Input:                                                                                                                                */
    6 F: N8 ^" E) t5 I. n/ O+ d* ~5 ?
  437. /*                None                                                                                                                        */( H% \2 l2 K6 M4 L, [
  438. /*                                                                                                                                                */
    0 N( U- \0 Q# L- G0 [/ k7 q" t6 [
  439. /* Returns:                                                                                                                                */* ^. c1 H, q% g- G, H& A
  440. /*                Nothing                                                                                                                        */
    " y+ v. x$ `4 `6 C9 ~" o
  441. /************************************************************************/
    0 ^/ O2 q0 Z/ f8 y
  442. void EBSY()
    1 p7 C5 i6 \% J' B+ e4 F- K1 P
  443. {0 t& H- L6 U4 Y, [8 X. S) I: P' c
  444.         CE_Low();                                /* enable device */  ?' k- e3 W( A. l0 p8 b/ b
  445.         Send_Byte(0x70);                /* send EBSY command */4 L$ W& I9 |& r! N$ ]
  446.         CE_High();                                /* disable device */
    0 a5 c, W+ f9 I; C5 u
  447. }) o) D5 A1 c$ i8 o4 m& c

  448. ! g" q# W: N- k
  449. /************************************************************************/
    / ]# h1 s& B7 q8 b9 v* K! V7 ]
  450. /* PROCEDURE: DBSY                                                                                                                */: b3 [0 N! A4 b9 q
  451. /*                                                                                                                                                */# s3 u) k  A0 @3 A: z2 g
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    # a. U/ d* M; f; U
  453. /* programming.                                                                                                                        */
    * ~( I+ m1 ~- P- n5 l
  454. /*                                                                                                                                                */
    , G& }1 e# X7 L% s$ g8 `
  455. /* Input:                                                                                                                                */- W, V# }4 P, `+ P& D. ^
  456. /*                None                                                                                                                        */
    + [* }0 l" R5 T# V# C6 \! ~
  457. /*                                                                                                                                                */
    . j# }" c3 P8 e# _: k6 o3 T
  458. /* Returns:                                                                                                                                */
    0 X' P0 e$ J8 [! M
  459. /*                Nothing                                                                                                                        */
    7 V4 g5 [. Z/ A" {1 L
  460. /************************************************************************/, J5 n1 V% P9 {3 q! |" H& |
  461. void DBSY()' C6 M. ]5 F' q! o+ t
  462. {# i6 \5 p3 a: x! m/ {6 k; l  N( ^
  463.         CE_Low();                                /* enable device */) M! A8 t5 q# P; J% J- H
  464.         Send_Byte(0x80);                /* send DBSY command */" {% n9 d: O! ?0 `8 Y- c9 ]; M
  465.         CE_High();                                /* disable device */
    # p3 h6 ~' f; t9 W! Q2 Q. X
  466. }
    5 V# P0 O5 A2 Z# ^
  467. 6 O, h3 ^8 L4 Q2 A' J! ^. S# r- e
  468. /************************************************************************/& E' O6 B+ a3 U: Q6 l- d
  469. /* PROCEDURE: Read_ID                                                                                                        */, ]' P9 ]9 }7 [
  470. /*                                                                                                                                                */& ]. p& }1 S5 h3 `* B4 p3 Y# ]0 [
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */) z2 @& j& v  Y3 U
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */8 Q; H6 T( Z3 |! B
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    , y6 h* T1 _& W' y% Q
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    # ^) I  e3 s' v# R0 O0 V/ k& c
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    0 f% S  r0 D! C. Q. D
  476. /* variable byte.                                                                                                                */
    . z. j% S4 e* E( m# g
  477. /*                                                                                                                                                */
    # ?& Q  s3 N9 a2 C0 _/ X/ W- L
  478. /* Input:                                                                                                                                */* q$ w; {8 r3 e
  479. /*                ID_addr                                                                                                                        */
    # C( E* Y. K" P1 f0 j+ q8 T2 M
  480. /*                                                                                                                                                */
    0 f+ W$ n: Y; E# C. ~7 u
  481. /* Returns:                                                                                                                                */
    # M6 S2 X* M3 [% C# {9 B
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    ) k  w0 b; O% p$ T4 L- L
  483. /*                                                                                                                                                */
    ) K" V2 c8 m; B) U3 n
  484. /************************************************************************// T! H% V% u) p% m  p/ Q" J' C
  485. unsigned char Read_ID(ID_addr)+ h( T+ g4 M% N" t7 I6 t
  486. {
    8 o* n/ g+ K5 w% s* A* P3 T
  487.         unsigned char byte;
    8 b, y+ o$ f' k8 |- _- t" i
  488.         CE_Low();                                /* enable device */2 H  X3 D9 w0 D9 L$ b5 \2 s& ~9 w. h
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    % y$ K  }+ N3 ?5 [% u
  490.     Send_Byte(0x00);                /* send address */3 I" N, ]- D+ z* f2 D/ t$ Q6 Z
  491.         Send_Byte(0x00);                /* send address */
      |; U/ g/ p+ U' O8 @
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */+ H$ M- o9 R3 p4 f8 Y- Y* U
  493.         byte = Get_Byte();                /* receive byte */. m' G) U* {0 o( l, F
  494.         CE_High();                                /* disable device */4 p3 L5 ?; t" G( j4 w1 S! N) d
  495.         return byte;
    2 [" B. e, r7 P' Q& v
  496. }
    & q2 v# d( E, t2 X
  497. 7 v; b. @! q: {
  498. /************************************************************************/( F4 ^& H) [5 e7 Q
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */4 F6 R  C0 L) m& v! i' {
  500. /*                                                                                                                                                */
    ; i0 G+ w. l  f, ?' d6 c
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  *// Q% y6 l! u+ X1 f) I) T& c* H7 V
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    + J  s1 `9 |4 {) n' h* M! Q4 F4 S3 X
  503. /* Please see the product datasheet for details.                                                  */8 `8 [7 r% v" g
  504. /*                                                                                                                                                */
    % N0 p4 {8 B7 e2 ^8 a
  505. /* Input:                                                                                                                                */) s  {  Q" }/ E% F
  506. /*                None                                                                                                                        */
    ; i2 J2 v1 r3 y5 U* f. e: \; v
  507. /*                                                                                                                                                */
    1 P& f2 L* t7 a" J& n# B. e
  508. /* Returns:                                                                                                                                */
    * k9 m, N8 F: C5 A$ \4 L) D
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */: f' _  x3 @! a/ [7 k
  510. /*                 and Device ID (8Eh)                                                                                        */+ p% E' D& H* ?) j$ {1 T) [
  511. /*                                                                                                                                                */
    $ \! w2 f7 i* l/ y8 h4 I
  512. /************************************************************************/
    ! w3 b4 o) I8 f$ ^
  513. unsigned long Jedec_ID_Read()
    * o* ]* [5 z7 `0 X% Z- y
  514. {
    7 b5 w6 g  g# C* z7 m
  515.         unsigned long temp;
    7 \# c. I$ `1 m3 c5 O
  516.         / i- o- M/ Z$ i9 ?" |
  517.         temp = 0;- n3 q' t9 B* }' Y8 W- q
  518. ' G! e2 @" O  p: ~7 C7 y3 l
  519.         CE_Low();                                        /* enable device */! r; Z3 L* l( [
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    4 M- M( V: ?$ j$ Q
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */; v8 v5 ~( r- k( K! P9 y
  522.         temp = (temp | Get_Byte()) << 8;       
    : A8 f; M2 {1 @* r+ D% b  c
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */! Z0 e2 M2 s: U4 c
  524.         CE_High();                                                        /* disable device */
    : |, r" X2 [( F: R
  525. % w% q$ ^- ^' d& W
  526.         return temp;1 [# X7 ^8 L: H& Q' Q7 |9 ~
  527. }
    & p/ m* O( V: J! }
  528. $ X- X) @0 ~- g5 O$ `/ \
  529. /************************************************************************/8 |7 }: T4 E1 L' J
  530. /* PROCEDURE:        Read                                                                                                        */) C6 D& z# a5 w  G# P& T
  531. /*                                                                                                                                                */               
    4 w2 I4 K2 q, w3 B+ L# [
  532. /* This procedure reads one address of the device.  It will return the         */# c- ^% V" G# l+ \- s1 M
  533. /* byte read in variable byte.                                                                                        */
    4 ], O8 J2 W' R5 u9 S* w* A5 c
  534. /*                                                                                                                                                */
    " [$ c" V. r7 c1 M9 x  O: a
  535. /*                                                                                                                                                */
    * B& Y% i/ U3 ]6 }! ^- ^& o
  536. /*                                                                                                                                                */
    2 e0 i1 _/ O. J1 J
  537. /* Input:                                                                                                                                */
    ! I* p2 p5 @9 w. W' W0 k5 H2 f
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */' n. R7 Z  V5 W1 x
  539. /*                                                                                                                                      *// d1 R) F8 X$ ?0 i
  540. /*                                                                                                                                                */
    + N! X' F) d1 h  F
  541. /* Returns:                                                                                                                                */
    / b" `2 N2 c$ U) G6 C3 j
  542. /*                byte                                                                                                                        */" C8 \* B! d! H- _) P6 m/ A
  543. /*                                                                                                                                                */
    $ P/ x5 t7 q9 [* O2 _. N# X& m, D
  544. /************************************************************************/
    % U9 ~9 X* J4 n9 a$ y/ ^! K
  545. unsigned char Read(unsigned long Dst)
    9 k: h9 h& s3 u: a0 c( u
  546. {: x3 _- \! e* h- {
  547.         unsigned char byte = 0;       
    & K$ y$ W4 x1 i$ u4 N
  548. & x  t9 W* ^( B
  549.         CE_Low();                                /* enable device */) F6 f1 m" _" G- p
  550.         Send_Byte(0x03);                 /* read command */' t% [& U# E2 s  U( W( c: s) }  K
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */$ z4 d+ C; `0 ^2 z, \5 z7 ~# [( N
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    : J. x* M& c8 ~' V% h$ o
  553.         Send_Byte(Dst & 0xFF);
    8 w0 E7 K2 r& X# n. X, e
  554.         byte = Get_Byte();
    5 ^- i7 `2 u! b4 X7 w7 Q* ~* N
  555.         CE_High();                                /* disable device */. C5 l. L# l8 p4 X  x5 u
  556.         return byte;                        /* return one byte read */
    4 v# u' L0 V7 r5 f6 e% f
  557. }# A) O" J) h+ s& E9 `) T: b* r! x

  558. / a, n! I( l* N5 D
  559. /************************************************************************/
    # c, [# h+ o$ o# S
  560. /* PROCEDURE:        Read_Cont                                                                                                */8 H4 T. l. O0 {* H( z
  561. /*                                                                                                                                                */                3 V# @" v0 I4 f. d
  562. /* This procedure reads multiple addresses of the device and stores                */! g  h3 H; f8 ^* q
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*// n  G  X5 }  i
  564. /*                                                                                                                                                */
    / a" I3 r5 N5 o4 B$ {% |
  565. /* Input:                                                                                                                                */3 w/ L! F( Z7 {9 f
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    / ]' j1 \9 j' d1 H% C+ j/ b- T# M
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */7 j& k4 P0 i0 ]+ g0 `2 s8 j4 O
  568. /*                                                                                                                                                */* y& Y5 W& Y  A& A
  569. /* Returns:                                                                                                                                */
    : e6 Q3 P) K; `  `- t" S0 ]
  570. /*                Nothing                                                                                                                        */
      u1 z: o) |! W* J0 }4 P  ]; U
  571. /*                                                                                                                                                */1 _& c# ?5 y5 N, j/ K* K6 c
  572. /************************************************************************/
    6 s1 l# ^& }- Q6 V
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)% T8 z/ r/ t/ m
  574. {
    & S' Z, T+ J/ M4 `
  575.         unsigned long i = 0;* e4 B8 K0 \1 j8 A- }" |
  576.         CE_Low();                                        /* enable device */0 z0 t4 L/ W- J9 D) H
  577.         Send_Byte(0x03);                         /* read command */
    & ~) M( w! Y: a: p( n/ j
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    . w1 W: H& Z( R4 s! ~
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    0 Q! W9 s# ?- b; Z' u; A
  580.         Send_Byte(Dst & 0xFF);
    6 I/ d; g- H$ ~( v
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    & ]: U/ B: b' n
  582.         {
    - z! O- R2 P. B8 K
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    % g7 }3 l; [6 O7 G. i0 L  \" a, d
  584.         }* X- n- w5 ~% q$ z7 Q7 G) P
  585.         CE_High();                                        /* disable device */9 i  C$ x* y; }% x2 l1 I
  586. . s' U7 l: D* V5 q" j, t+ a3 f8 a
  587. }' e* I( N; C& |

  588.   S$ _7 J6 f2 G- d
  589. /************************************************************************/8 q2 E7 u/ D5 x6 J' _1 a
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    " E+ M, m+ y0 w. d; g& s7 ~
  591. /*                                                                                                                                                */               
    5 u7 ^, A' M# A) \7 K5 V9 e
  592. /* This procedure reads one address of the device.  It will return the         */7 B$ P3 V, M2 v% R, g
  593. /* byte read in variable byte.                                                                                        */% a8 a  f& ^4 T0 W
  594. /*                                                                                                                                                */
    9 O  ^! x. H% n% X8 G
  595. /*                                                                                                                                                */; s# |  R2 O6 d
  596. /*                                                                                                                                                */
    9 h' X7 H* e5 `2 }
  597. /* Input:                                                                                                                                */5 |, ?, r; |0 ~9 \
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */+ r0 X" @3 z( M6 @1 l: _. G$ I( g
  599. /*                                                                                                                                      */( b& K: s9 c4 N* A  p5 Z
  600. /*                                                                                                                                                */
    / H3 s" i0 c# @
  601. /* Returns:                                                                                                                                */3 @  B* B  e- ?& q( C2 l" r+ ?. x
  602. /*                byte                                                                                                                        */1 |4 E4 @: l" T8 W* X
  603. /*                                                                                                                                                */! M8 ?6 l4 H/ J( O2 t
  604. /************************************************************************/) s* x. n3 E8 e) G, E
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    & N. s8 q: E+ m; M+ }9 O( f7 e
  606. {
    ; w0 P1 C5 b5 Z( K: w6 I' V- ]
  607.         unsigned char byte = 0;       
    ; H, Y3 I' P9 X. q! r: E' D

  608. 9 O) W6 X/ e8 k, ^! r( v
  609.         CE_Low();                                /* enable device */) I9 ]2 L$ x1 f# K/ Z) E
  610.         Send_Byte(0x0B);                 /* read command */
    - |6 ?) t5 k# P) k) Y. z
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    6 V  x. ]& o! V1 b' J! q- O9 @8 r
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    1 @- f" |$ I( i! ]  Z) U4 k0 K5 d( m9 P8 R
  613.         Send_Byte(Dst & 0xFF);3 U- t' G) a6 D7 }5 s" a
  614.         Send_Byte(0xFF);                /*dummy byte*/
    8 U, v$ s5 s2 q6 {$ B! J
  615.         byte = Get_Byte();
    : g& v( Y4 r8 ]! w
  616.         CE_High();                                /* disable device */; ?" G  F; h" ]0 ^
  617.         return byte;                        /* return one byte read */
      i  ~: ]' n( S; l3 G6 n  _
  618. }
    . S* w* ~5 V* N/ \9 V3 \5 \

  619. % `8 L) Q, W2 K- d7 c9 a
  620. /************************************************************************/* r9 \& t- Y/ [, ~
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */: O; k4 V0 ^! K+ n7 _
  622. /*                                                                                                                                                */                / b  n9 E" z' u4 m. v# T& B
  623. /* This procedure reads multiple addresses of the device and stores                */5 K' q" W. R( d/ ~
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    7 r8 Q' E( ^5 K$ d
  625. /*                                                                                                                                                */( Q1 q" P2 i7 ]% y0 Q5 p$ A
  626. /* Input:                                                                                                                                */; p: w! M5 t- S. k' W. D
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ) }7 F" A( S5 a( Y9 e* f+ I/ E2 q
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */' f, p3 Q, d( Z7 v5 d
  629. /*                                                                                                                                                */
    - v. f0 z1 E. a2 ^
  630. /* Returns:                                                                                                                                */# f% s4 Z/ v0 S0 y3 E: F
  631. /*                Nothing                                                                                                                        */
    ' @% q, y5 _- E+ P
  632. /*                                                                                                                                                */3 w; s- t4 ^6 R! m* Q$ _
  633. /************************************************************************/' s% F4 i! B8 H: Z- ?! N- r
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    & o! g5 Q. b: Z% h
  635. {; W* z, ^% j% o1 b8 Z5 ?
  636.         unsigned long i = 0;
    ) O! b2 p9 O# r6 X
  637.         CE_Low();                                        /* enable device */
    $ o$ L  T1 ?' s8 O! ]
  638.         Send_Byte(0x0B);                         /* read command */
    " S* l2 x, \' g6 g# K4 v8 M* N
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */% q- i/ O) G- K8 c
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));/ t! {" R9 U' r# u. q" X1 D
  641.         Send_Byte(Dst & 0xFF);# E  E1 S* Z8 K. F) y
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    ' h! X7 e) f: L  F7 b8 N
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    3 Y/ g  e" ?6 d- w- s
  644.         {
    : u. }( O2 X2 J
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */" Z. V- |! H  D
  646.         }
    & t5 m' P4 T1 x- U9 ~
  647.         CE_High();                                /* disable device */
    4 h' `. n. H% X# h9 v. G: p
  648. }
    7 s0 i$ _" ]$ O$ t+ b
  649. % @0 e, {2 y8 A  C% `9 E! D
  650. /************************************************************************/5 h' p- H! J, d& o& N6 q" A
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    7 J  C' o) ^& _6 }! C; X+ F+ G2 P
  652. /*                                                                                                                                                */! z) S5 m. m) d# u/ H! g
  653. /* This procedure programs one address of the device.                                        */* U3 G# C' k+ c6 O
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    4 }+ a: i- G3 r. a& C+ d
  655. /* block protected.                                                                                                                */
    - f) F% E0 Z  E5 ~8 N
  656. /*                                                                                                                                                */5 q! D) R. s1 E
  657. /*                                                                                                                                                */
    / E( s' v$ N8 M
  658. /*                                                                                                                                                */( ]- A7 J: C' T7 Q/ R& l
  659. /* Input:                                                                                                                                */6 p: J" z  N3 S7 t# ~
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + o# w: F7 ]: g/ B
  661. /*                byte:                byte to be programmed                                                                */( a1 `6 N$ p3 `
  662. /*                                                                                                                                      */
    ! R8 ?4 P2 D( M- p
  663. /*                                                                                                                                                */
    1 s. M2 g6 I( w
  664. /* Returns:                                                                                                                                */6 |( e  A& h: g1 `# B6 g
  665. /*                Nothing                                                                                                                        */, y2 N3 ]  s" a
  666. /*                                                                                                                                                */$ m- s- }* B: E- w# p4 X0 z
  667. /************************************************************************/0 p3 j8 Y; j6 ]' v( N8 E2 F; {3 U1 h
  668. void Byte_Program(unsigned long Dst, unsigned char byte)/ h/ y2 e- I7 k! J3 E6 M
  669. {& t6 T/ P1 \0 |
  670.         CE_Low();                                        /* enable device */7 P7 E; N, @( u+ p
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    4 A/ V, T5 v4 o6 M, s# o  @
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ; P( n" f; `5 c7 y6 }
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    3 l0 H& ~1 f- h# |  B" j% J8 a/ v
  674.         Send_Byte(Dst & 0xFF);
    ) X8 G+ j5 k+ w9 R/ |  m% ~
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    ) y; f% d, r- C4 b2 @3 N/ G
  676.         CE_High();                                        /* disable device */8 S* `+ R$ i: @' `, h
  677. }
    $ B! N5 R3 }! d  b! I( P( @
  678. . A, E$ D( |1 C: j1 v8 {6 r
  679. /************************************************************************/& W; j  _+ Y9 R0 E( k+ @: m
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    , ~9 i/ L5 |, Q* K9 Q* n& M
  681. /*                                                                                                                                                */4 e9 C: {$ T2 @# r2 F7 s) i* `! L
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    4 l6 @8 H; D3 r5 x5 x
  683. /* the device:  1st data byte will be programmed into the initial                 */$ @. E( Z4 _' X
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    # h. |# z9 x4 n+ ?
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */8 D; Z9 P& C' ^5 T  U0 C" }0 d
  686. /* is used to to start the AAI process.  It should be followed by                 */' e/ |% k8 t) x/ f% u
  687. /* Auto_Add_IncB.                                                                                                                */
    / |# C4 R7 j* ~. Y- q1 t
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    ( U& H/ M; W9 K+ |0 b! i
  689. /*                                block protected.                                                                                */% \$ r0 T* M  N6 u
  690. /*                                                                                                                                                */
    ! M0 a5 P/ Q5 V4 `3 `
  691. /*                                                                                                                                                */
    6 R: \3 F9 i) i$ R& @% G
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */4 a; J, i- L: ?9 n8 {$ ]) s; c3 Y; L) \8 E
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */* A- Q" X- w, C7 R/ z% B
  694. /*         unless AAI is programming the last address or last address of                */
    0 \5 ~- a. a5 T
  695. /*          unprotected block, which automatically exits AAI mode.                                */9 o( H( v9 a' d
  696. /*                                                                                                                                                */
    / r' G, W, X: b( W$ |* K
  697. /* Input:                                                                                                                                */9 ~0 S. k  M' O$ C+ ?/ M
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */2 ?; W5 N( Q" `6 L1 R0 e
  699. /*                byte1:                1st byte to be programmed                                                        */
    ; |* d# m! j2 ~" _9 n
  700. /*      byte1:                2nd byte to be programmed                                                        */
    ) U9 a( r" M! {6 H3 B" d4 ~
  701. /*                                                                                                                                                */' }+ b& |( e1 j6 F  N" n$ S4 V
  702. /* Returns:                                                                                                                                */9 |+ k1 ]0 I$ n; m% R9 d
  703. /*                Nothing                                                                                                                        */) E& t* P, E/ h) W
  704. /*                                                                                                                                                */
    % J/ y5 k$ H3 w6 W. y
  705. /************************************************************************/% Y- l, s8 x6 o+ i0 n8 z6 M4 _0 ^
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    . J0 e+ ~& t0 P6 _! ?5 l4 |/ Z
  707. {
    ! v( ]6 h1 x9 F: _
  708.         CE_Low();                                        /* enable device */
    1 Q5 Z+ E9 X& L" u/ }$ w
  709.         Send_Byte(0xAD);                        /* send AAI command */
    6 g- d. Q! [9 y) N1 e; V3 k( p* A7 ~
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    * e. Y8 p; R) x) {8 \2 D
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    # r  D+ h3 c1 P  a
  712.         Send_Byte(Dst & 0xFF);! E0 N, j% n9 @+ Z; O9 ~' T
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        $ L" ]% C- `! _" z) y- L
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */: ^0 y# ], D3 y+ S  z# j% I
  715.         CE_High();                                        /* disable device *// ~; O; e6 u% x& D4 r: W) C/ O
  716. }  P5 ~/ K' E* V: i  Z

  717. 2 b! s* F) i$ C
  718. /************************************************************************/2 ?2 F7 }* x( J9 Z  e# ]9 \, g3 ^
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    0 \: N6 e. Y1 }' p
  720. /*                                                                                                                                                */1 j- O" w, G4 h4 Y: d! L5 \) H
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/) c6 N0 P9 r/ o; n
  722. /* the device:  1st data byte will be programmed into the initial                 */) V# x2 ]6 S" d3 [2 P
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */, g8 {# @5 Q# v
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */; H. u  @- F2 q8 ~3 i. f7 x
  725. /* is used after Auto_Address_IncA.                                                                                */5 R  C, R2 U8 v+ j) W3 e/ A& ^
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    ; O0 R7 A; h5 b  p
  727. /*                                block protected.                                                                                */
    , m& }' E& [# @# b9 b* _  o
  728. /*                                                                                                                                                */
    2 p$ k" v9 U7 O
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */! L2 K3 N) Q0 @0 q
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    7 Y4 p0 W* @+ o" A" [$ m
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    % T3 W- C) O7 N, o. Z
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    # k/ n/ v: _$ ~5 C
  733. /*         last address of unprotected block, which automatically exits                 */+ x: }; D& V. a. N
  734. /*         AAI mode.                                                                                                                        */) W9 G3 J$ b" `- y* P
  735. /*                                                                                                                                                */) o, J; f7 m- N. }7 M- v5 b
  736. /* Input:                                                                                                                                */6 S) ~1 S7 M2 L7 F5 i4 V
  737. /*                                                                                                                                                */
    0 w1 y0 G# ~4 _& Z
  738. /*                byte1:                1st byte to be programmed                                                        */& m1 M, w/ {. {
  739. /*                byte2:                2nd byte to be programmed                                                        */
    3 ~6 L* Z; Z9 N0 A* o9 L( J
  740. /*                                                                                                                                      */
    0 ~5 x5 l% u; \1 P0 f8 b1 b
  741. /*                                                                                                                                                */# z- E) O$ }, X3 t( H/ O
  742. /* Returns:                                                                                                                                */
    , E$ ^& F% N& W! u' d% \8 O: B6 e
  743. /*                Nothing                                                                                                                        */0 H% D5 ]2 w8 z, ?
  744. /*                                                                                                                                                */0 t2 q3 L9 p4 J% i9 v5 |( W5 X
  745. /************************************************************************/
    0 y! \% K9 f! L$ K$ b1 s( `
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    4 I8 j4 v3 v- c( |. z
  747. {6 E' ]0 v" ?& J% ~9 V: w0 C
  748.         CE_Low();                                        /* enable device */
    7 R5 @/ h4 u+ b3 d, {/ ~8 S8 K
  749.         Send_Byte(0xAD);                        /* send AAI command */
    8 ^& c2 F6 \  a8 O2 N4 C
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */) u) F* M, v4 E7 u; T
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    6 Q! b0 ], W! ~
  752.         CE_High();                                        /* disable device */) H5 ^, [- H: I- D& @
  753. }9 u0 O& C: V4 `: ^0 G

  754. 5 N. `% B( @4 U; V% ^
  755. /************************************************************************/2 B" b* Q3 [2 k  U) w4 T
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */* R4 |5 e, k0 z! z
  757. /*                                                                                                                                                */
    3 U/ @" t7 I7 F6 X. y+ h0 B
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    9 R5 X  g, y3 P- Q" z: z) E! R" m
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */) N9 N5 f$ m& i1 P- _
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    ( Y6 u" @  Q7 ]! x+ \5 ^6 w
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */* z0 D6 {3 U2 ?8 R  j! s+ e& F
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */" u, P: \8 P0 b$ B1 f3 l# D
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    - A% K& G7 u2 e9 J! X0 |
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    . |) O  K% ^* B6 x$ Q% y2 ~
  765. /* Assumption:  Address being programmed is already erased and is NOT        */1 i, ~# l4 y, Y: _$ y( V0 z: ?
  766. /*                                block protected.                                                                                */
    . d2 @' s2 e: q: a0 L
  767. /*                                                                                                                                                */1 n& w) |& b% a  }7 c$ [9 a
  768. /*                                                                                                                                                */! X+ A+ C8 k( h* F
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    " e) }9 [1 }0 b: K' x8 C: y
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */3 i( d8 h, P. }* M" P% g) ]
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ) d& x, j' d0 Q8 j% Z
  772. /*          to exit AAI mode unless AAI is programming the last address or                */8 P4 U* q/ |: E) ]) S
  773. /*         last address of unprotected block, which automatically exits                 */
    & y3 P1 q/ {1 R( w( o" l
  774. /*         AAI mode.                                                                                                                        */4 ?2 u0 J4 [: ]6 L  P: T
  775. /*                                                                                                                                                */
    . @! g7 Y. B' c/ u' [4 U/ l& o
  776. /* Input:                                                                                                                                */7 H" X4 {2 M/ ]7 p4 `- X
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */) ~& r' e" R" y& e6 Q4 B
  778. /*                byte1:                1st byte to be programmed                                                        */1 F% I. [4 i3 E& B5 ~- N
  779. /*      byte1:                2nd byte to be programmed                                                        */! e- I7 j. f' p$ }- z$ D
  780. /*                                                                                                                                                */
    . i1 f1 Q9 {3 d2 J* L1 y
  781. /* Returns:                                                                                                                                */- L3 L0 M# E/ G9 D7 o
  782. /*                Nothing                                                                                                                        */' g+ a/ K8 d7 B+ L7 Y2 ]
  783. /*                                                                                                                                                */# t9 [5 N5 t6 s6 }" {
  784. /************************************************************************// O: ^7 x+ J# Q! F) [8 T* t
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ! Y) M8 W9 R5 k/ @. ~! O2 M
  786. {
    7 ~( Y, ^8 d. B
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        $ B$ z7 F4 k8 x1 H0 a( J( N6 m6 s

  788. 1 h5 n& f& R* f# p5 {
  789.         CE_Low();                                        /* enable device */4 g: {" e& g! G) \% \( v
  790.         Send_Byte(0xAD);                        /* send AAI command */; H  y9 o2 [5 A) x. U
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ! l/ D* s( }% E# `2 [/ z+ _" m' h+ C
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));$ ~; e! o% m8 E' p2 Q: g4 _. ~
  793.         Send_Byte(Dst & 0xFF);
    4 ]7 b$ c+ C' u5 u+ Y" |+ @$ J
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    6 s! b6 m" }) b6 x
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */; `+ [- D( N6 R
  796.         CE_High();                                        /* disable device */
    3 M) x, S' @# \' R0 ^7 g* J2 V
  797.         - L; R; s5 J# v7 \0 V
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */) i: l% Y& H% Y5 {0 A/ \, K
  799. + m) w' e' p2 M( f: O
  800. }1 j8 d/ J4 {! P7 j( c
  801. ( g! K4 _  v1 u" A& X
  802. /************************************************************************/8 O8 R! k* r8 T0 t0 C3 E1 c, t0 z
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */: K8 `; S) y4 T# b5 q
  804. /*                                                                                                                                                */' J3 x7 J; u, V; j1 o
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */: M8 I$ F, C; x) z) U
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */3 T9 }( x, R% b7 y, \& I% F
  807. /* AAI programmming is completed.  It programs consecutive addresses of */0 u6 g" H5 F# s; ^* ^9 R$ K
  808. /* the device.  The 1st data byte will be programmed into the initial   */+ b: R2 j1 n3 M" N
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */7 K. {& V$ v, f& F
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    4 T& V! z+ \; r4 c. e  H0 |' ?
  811. /* used after Auto_Address_IncA.                                                                                */) J: a' E5 ]/ u7 _( y1 r' F3 _3 U
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    . X& Y9 Z: i  F* A4 [- z9 w/ ]
  813. /*                                block protected.                                                                                */# ?" H+ \% m( i+ R5 K
  814. /*                                                                                                                                                */0 h7 S0 w" V* k7 L
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */. x; O) |" c7 R) Y' T# {- O3 a6 ^
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    1 ?2 I* q8 ]  b- c$ m
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */! h! M. c. S. Z! b. |' l
  818. /*          to exit AAI mode unless AAI is programming the last address or                */. r/ ?" X+ `7 [
  819. /*         last address of unprotected block, which automatically exits                 */
    2 c( R; }0 t9 q$ ~" I) m
  820. /*         AAI mode.                                                                                                                        */) }9 ]) Q: @0 ?, G4 x, R
  821. /*                                                                                                                                                */# c. u$ w" Y4 ]# k- I! _  u
  822. /* Input:                                                                                                                                */
    8 N# O7 L( G# Y
  823. /*                                                                                                                                                */
    1 G9 r, g: X5 b3 U
  824. /*                byte1:                1st byte to be programmed                                                        */$ z+ s. ~) A2 s7 _
  825. /*                byte2:                2nd byte to be programmed                                                        */( G' N6 s' Z2 ^# R
  826. /*                                                                                                                                      */
    - B+ A3 f4 L/ R8 X- \! t" C
  827. /*                                                                                                                                                */% a0 @6 @4 Z! U! q( t# P5 i* x
  828. /* Returns:                                                                                                                                */
    % w9 s3 `# k* U$ r" |: S$ D
  829. /*                Nothing                                                                                                                        */
    ' d, F  I" o& [; F8 w6 N1 |
  830. /*                                                                                                                                                */
    : S* O1 D/ [9 z, x. [1 y* e
  831. /************************************************************************/8 s2 y: w$ U/ v/ K6 o, }  y
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
      ~4 v8 X" M  w0 s+ l
  833. {4 Y' i9 X0 a% F  U* P' M5 t, Z* N
  834.         CE_Low();                                /* enable device */, D0 K. s3 e: y! K0 @4 @
  835.         Send_Byte(0xAD);                /* send AAI command */$ ?& u0 |1 r* I* }: x( u8 i8 i
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    " C$ Z+ X6 i* A
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */. c4 m0 U. c% ~4 U9 u
  838.         CE_High();                                /* disable device */
    + Y* A! ^! |+ O# g8 Y: p: u5 e

  839. # t4 x+ _1 u" M5 n
  840.         Poll_SO();                                /* polls RY/BY# using SO line */3 |% f/ i9 l3 u; h' C

  841. 9 c/ m& Y; `  w" V* Y  r% O8 H
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    ) @! D0 Q$ |. C
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */3 J& K: {# S7 X' q1 U5 T0 w" u7 i
  844. }
    1 K& _- U+ y) M- s

  845. . _$ T0 G; V& }( ^8 |& `# Q$ |
  846. /************************************************************************/
    : ~- j6 u( e4 U( h
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    5 w; n/ W9 @7 _  n* f
  848. /*                                                                                                                                                */; `8 ~$ }% d! J6 ]) H
  849. /* This procedure erases the entire Chip.                                                                */  o/ X+ k$ c9 t
  850. /*                                                                                                                                                */! r$ V  \1 s. u: x
  851. /* Input:                                                                                                                                */
    4 @( X6 a5 L0 P5 @6 G8 h! B# P
  852. /*                None                                                                                                                        */4 \( ?, E; z9 A' Q0 z
  853. /*                                                                                                                                                */% ?! L5 H% {+ F0 @! ]
  854. /* Returns:                                                                                                                                */& e0 [- f3 B0 D) R8 h7 G: M% T
  855. /*                Nothing                                                                                                                        */( s1 H1 W* ]8 x/ r- W; \
  856. /************************************************************************/
    $ B8 A. X' F, m* _2 g4 q" ~5 ^+ e
  857. void Chip_Erase()
    / i. h+ P1 G/ ^
  858. {                                               
    * l: Y2 P3 \$ X) K0 Q
  859.         CE_Low();                                /* enable device */
    ! c8 u5 V0 N% r0 ^! g5 e( o
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */' R  s4 F+ Z1 s4 |
  861.         CE_High();                                /* disable device */2 R8 W# j: ?0 c6 c5 K. E$ N% M
  862. }
    ) Q. Z& s: S* L& i

  863. 1 f) p7 ^$ z4 D6 d9 ^% a( p  P: i
  864. /************************************************************************/6 U2 A; V0 i3 d1 ], F3 Y2 d
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    8 k0 c, Q1 I2 U8 M/ T& \& O, g
  866. /*                                                                                                                                                */8 H, e; p+ {% p9 x
  867. /* This procedure Sector Erases the Chip.                                                                */
    7 B1 b6 a3 E0 I; ^/ W$ j1 Q1 f
  868. /*                                                                                                                                                */5 V" y# z9 n% O! P0 z) p9 Y/ j
  869. /* Input:                                                                                                                                */
    , V) @- t/ l4 P
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */( u4 D5 ?; y3 g. d* }5 S8 w2 }
  871. /*                                                                                                                                                */8 h8 S4 K9 ~6 c6 m4 W: s
  872. /* Returns:                                                                                                                                */
    ; c$ h8 t, L; ^5 \3 E( b* @
  873. /*                Nothing                                                                                                                        */6 j) S0 Z8 I$ k8 A
  874. /************************************************************************/
    2 n6 {+ x6 j$ y6 ?+ k! R: ]- d: E
  875. void Sector_Erase(unsigned long Dst)# ~9 d4 W; r+ A) `5 i: \" g; h
  876. {5 i0 f. A/ ]# s& f0 ]' q

  877. # o# O% z0 ~& _. S' Z$ F

  878. ( ?: s. L) q6 `. H1 e5 W% S7 I
  879.         CE_Low();                                        /* enable device */; w5 Q7 N, J' \/ Z- M8 J
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    5 M6 S/ u6 ^) k) b) [+ y
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */) {9 ~  \/ W2 ~$ I+ Y3 c
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));/ D( Z, K: d* ~' \+ K! D! w: X7 B
  883.         Send_Byte(Dst & 0xFF);
    6 ~; e- m0 I+ O  C
  884.         CE_High();                                        /* disable device */
    ) l4 G) B$ d8 [. K
  885. }        2 f# a& f" g; h  L, A* Z

  886. & V8 C3 D6 K" |# @+ m( f
  887. /************************************************************************/: H5 n) |0 I" B# q# Z( Q
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    & |0 q2 P% U- O2 `% @
  889. /*                                                                                                                                                */2 c: J2 |* T: P  n% _: t$ w
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */' s2 }0 A8 u* ]8 ?4 p
  891. /*                                                                                                                                                */: T) Z9 j: i1 T% y
  892. /* Input:                                                                                                                                */7 l& g1 O- L# J8 F
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    " }: h. v5 d" I2 t7 I
  894. /*                                                                                                                                                */0 j" X9 B( C7 C( V3 u
  895. /* Returns:                                                                                                                                */
    1 O, h8 j8 r% t# x" P
  896. /*                Nothing                                                                                                                        */
    " z( V  ^+ b7 `1 s( |9 V
  897. /************************************************************************/
    ; k5 V) i# ~2 v- ]) z/ o8 O7 z
  898. void Block_Erase_32K(unsigned long Dst)
    & P6 h! \9 k& C& [: H* V- o0 n
  899. {5 M3 s. U: q8 y# F
  900.         CE_Low();                                        /* enable device *// I8 f; |$ l4 y  k: l; h. p
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */5 B) ~, l  D7 p' z$ e+ o
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ; `8 m( D- d8 [7 j2 |' ~
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));6 X) N. [  d+ r5 S9 O7 c  M8 |) B
  904.         Send_Byte(Dst & 0xFF);
    8 b4 a6 j/ w* ~7 e- m
  905.         CE_High();                                        /* disable device */6 m  \+ u$ V. l2 c- h7 {2 F0 s# ~
  906. }, t& i1 h% H3 u

  907. ) O7 L- Y- e$ W) l5 p
  908. /************************************************************************/
    9 |4 q, D1 Z6 A! D3 L
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    ! O0 u$ d4 [5 ?
  910. /*                                                                                                                                                */- W1 n/ h% C6 f9 e: x' V
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ' ^8 k+ L* d2 T9 ^2 X6 r3 L
  912. /*                                                                                                                                                */
    ! j' Y- S7 P* H( J7 ?6 N
  913. /* Input:                                                                                                                                */
    . T9 Z6 L( ?4 d
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */- z- p$ _  R+ o. @& E& D1 p
  915. /*                                                                                                                                                *// h# L% {* |+ `+ l3 W" b
  916. /* Returns:                                                                                                                                */) a7 C* T0 |. C+ i- D
  917. /*                Nothing                                                                                                                        */* J1 h, C+ k. ^0 i/ P, f
  918. /************************************************************************/% [9 v# ^5 H' Z) v$ ?7 e3 [  }
  919. void Block_Erase_64K(unsigned long Dst)9 o( Q" Z! H) y: }5 b" ]' y
  920. {5 p- p/ e4 h' A$ V$ B$ e5 J8 ]
  921.         CE_Low();                                        /* enable device *// E) |( Y. ~" h8 K/ T8 h+ @
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */' a" f! M- N$ f! k% G+ k, k- J
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    $ A7 U6 ^: k" o: l
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 F4 Q8 Y' W3 g- O& s
  925.         Send_Byte(Dst & 0xFF);
    0 l' T# ?6 ~* t6 l! e
  926.         CE_High();                                        /* disable device */: u9 w9 o) g& C# L1 I) t
  927. }
    ! a, _2 _, Y8 w* p1 _

  928. / ^% t. q& C! d0 F2 U! x$ j. C: l
  929. /************************************************************************/
    + x5 V. [4 e* i1 E- {# b
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    0 t9 _; ~2 @6 H
  931. /*                                                                                                                                                */* Y" |- G1 f6 S$ F2 s1 A8 K: c) z
  932. /* This procedure waits until device is no longer busy (can be used by        */& E# Q7 N# v2 w6 j, t9 j7 D
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                *// G$ n7 o3 B3 N# E  _. M5 @$ c
  934. /*                                                                                                                                                */
    7 i  B: \9 N1 h" ^
  935. /* Input:                                                                                                                                */" h+ K  G: x, y1 B) a0 E5 r$ \, j
  936. /*                None                                                                                                                        */
    * x3 }  [2 Q7 ]" W6 O* \
  937. /*                                                                                                                                                */
    $ d6 V9 C& `- K, q: D
  938. /* Returns:                                                                                                                                */' T/ A; B5 ?$ j$ C0 f
  939. /*                Nothing                                                                                                                        */
    4 a& h. @& _. d
  940. /************************************************************************/
    % n" {; |+ ^5 G
  941. void Wait_Busy()
    7 b  p0 G0 b5 h5 h2 X7 W
  942. {
    * w3 i# q- H5 a! Y5 P; A! g
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */- }* g/ k* c8 g/ e7 K+ x" h
  944.                 Read_Status_Register();% c: R; Q& C% i7 f0 t* }
  945. }
    ) C6 _' N' v1 p9 Y8 p
  946. & M9 z6 Y' ~4 J8 e' B
  947. /************************************************************************/4 {2 `3 e. o5 ^+ l! R
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    ! f5 {( y) a8 @, w, V- L9 k
  949. /*                                                                                                                                                */- `' r# v. S2 M0 u( O
  950. /* This procedure waits until device is no longer busy for AAI mode.        */1 t% D* s, {1 J
  951. /*                                                                                                                                                */
    ; r3 u0 {, g$ g5 X% R% ]3 J9 V
  952. /* Input:                                                                                                                                */- c) |( W+ g2 S$ |
  953. /*                None                                                                                                                        */
    , z3 S) D7 y5 x1 q. z/ {$ X  Q8 C
  954. /*                                                                                                                                                */
    7 B) G/ T* z& _9 E2 B" O
  955. /* Returns:                                                                                                                                */
    % n9 R: c1 l. Y
  956. /*                Nothing                                                                                                                        *// C2 r' M7 K* h. _1 T
  957. /************************************************************************/
    ) i8 G1 q, ~( U1 i0 [0 R
  958. void Wait_Busy_AAI()* Q9 O, w) u1 _( _- V+ }# W
  959. {
    5 Z- x- l, I7 s& y' J  d2 Q; {
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */  \" v9 G+ @2 R6 _0 G% U
  961.                 Read_Status_Register();
    + R" S1 Q) X# N( b* u2 {
  962. }
    ( S3 L) R' W% I% {' g: i+ k, R# j6 E
  963. ' x7 G3 Z5 z* s# x, I1 E
  964. /************************************************************************/1 f; U5 Q% c. j
  965. /* PROCEDURE: WREN_Check                                                                                                */" d. X1 q2 x/ O6 N0 `% F- ^* U/ e
  966. /*                                                                                                                                                */8 k# |# c& t8 }" k8 k& r  B! _9 {
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    3 q. s6 ^  r, f+ Q5 C
  968. /*                                                                                                                                                */
    5 X( T$ I( s! i* a8 {
  969. /* Input:                                                                                                                                */5 f8 ]7 B0 ~+ [
  970. /*                None                                                                                                                        */, m) {  t4 }2 S. X4 d: C
  971. /*                                                                                                                                                */
    1 Z7 P& }& z- q
  972. /* Returns:                                                                                                                                */
    6 r5 M3 u1 \+ T$ D
  973. /*                Nothing                                                                                                                        */
    6 F0 |& U1 ^) c. S$ M3 J& E
  974. /************************************************************************/! K" v) ^, w# A$ X4 T
  975. void WREN_Check()
    + a, h" |1 V+ r% [- D$ h& h
  976. {$ A! W9 z; s+ q9 R! x8 e
  977.         unsigned char byte;
    / S0 q: O1 i+ I+ P: f: x; q* U
  978.         byte = Read_Status_Register();        /* read the status register */
      C' Q; s% C  L  r. T( }
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    / |7 R. d! R7 F# Q  n1 c+ z  g8 d
  980.         {
    5 Z& D( h! k# l* e, x
  981.                 while(1)
    7 t; E0 a0 T/ j9 K
  982.                         /* add source code or statements for this file */& p" }5 n( g; W+ f
  983.                         /* to compile                                  */3 z0 I% |4 N4 P& `8 ~
  984.                         /* i.e. option: insert a display to view error on LED? */
    4 u9 b+ q6 O. D) D: `
  985.                  
      d5 N! R. y2 g& L8 e" E
  986.         }
    0 e" {9 O" A2 E  K' e
  987. }
    ( S& N% s% ~( l  q7 ]
  988. ) r9 o9 j3 \0 V
  989. /************************************************************************/1 e) E- U3 }, Z5 [6 R
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    . F) W3 @( N% x  ?2 ^
  991. /*                                                                                                                                                */; Q& X  j5 [7 l& J) M& ?% D+ V
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    : b7 W/ J/ [3 e$ y! Q* C# T
  993. /*                                                                                                                                                */
    7 U* ~/ O$ H. W. ]: ~. D$ l
  994. /* Input:                                                                                                                                */! b3 k( }/ J" E2 T
  995. /*                None                                                                                                                        */3 E- [6 f% [  `- ~4 H; T6 @
  996. /*                                                                                                                                                */
    % M8 B0 i4 D- R2 r* X' k
  997. /* Returns:                                                                                                                                */
    1 i; @* L* h+ Q" Y
  998. /*                Nothing                                                                                                                        */
    8 G$ E/ W0 C" t! v+ ^! `. u6 H
  999. /************************************************************************/. h4 K( K' s$ E
  1000. void WREN_AAI_Check()
    ( Q+ z4 a# @# ^4 h2 K
  1001. {, Q! c1 D( p; v  r0 W+ p
  1002.         unsigned char byte;: E  V9 r" \# I2 Q6 g: y- s% K( ?
  1003.         byte = Read_Status_Register();        /* read the status register */
    - P; {- e# V% K4 u  K. l1 J
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    - Z) `- O# {0 Q4 j. }% g
  1005.         {
      L7 j1 ~+ T0 r# u
  1006.                 while(1)               
    . u- k4 z6 Q0 @
  1007.                         /* add source code or statements for this file */' ~& C4 B' H) J% D% x) K% b
  1008.                         /* to compile                                  */. f% q3 O7 G' `: f. Y; h6 }
  1009.                         /* i.e. option: insert a display to view error on LED? */0 w0 ^0 S1 i3 @( I
  1010. 8 Q0 P, ^: q$ P( Q3 Q2 S
  1011.         }9 T& r: l, F* t$ {' N( A
  1012. }0 B0 f# b, j  m2 t" e2 |1 G
  1013. ' M! c5 j" t8 ]: {
  1014. /************************************************************************/- B, X* E9 L7 e  F4 g
  1015. /* PROCEDURE: Verify                                                                                                        */
    ; `+ M: f! y4 _3 L9 a8 r0 D
  1016. /*                                                                                                                                                */
    2 |; H( x) k+ b+ \) z0 j$ \
  1017. /* This procedure checks to see if the correct byte has be read.                */
    4 o% n2 A+ e% _
  1018. /*                                                                                                                                                */
    * r; ~) z( P" e) w( c9 ~
  1019. /* Input:                                                                                                                                */- Z" y8 L- B" ~, N
  1020. /*                byte:                byte read                                                                                        */5 o+ z. x9 ~0 ^8 Z! T
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    8 `( x; o) I4 p
  1022. /*                                                                                                                                                */
    # |/ V) S& G6 ^  D, t% S, D3 R
  1023. /* Returns:                                                                                                                                */) P# Y' i% E/ a* f. ^  _/ ^+ U
  1024. /*                Nothing                                                                                                                        */
    . s( t9 a% D5 X* Y% |
  1025. /************************************************************************/
    0 H1 A+ C) K6 P) X
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    6 K: h  Q7 s0 F9 V
  1027. {
    ) U3 P: X$ N8 K9 Y1 H" V
  1028.         if (byte != cor_byte)
    ' P  Q. b, @  J7 C6 g  ^" [) [
  1029.         {
    % p% u" |5 y9 S
  1030.                 while(1)+ h, ]1 N0 C% J5 c+ j3 z( Y6 U9 ?
  1031.                         /* add source code or statement for this file */
    ; {* U( U, x, n+ X  Z
  1032.                         /* to compile                                  */; _+ e# z* V& W* X
  1033.                         /* i.e. option: insert a display to view error on LED? */
    0 ^, G  p3 J' R
  1034.                 1 P2 u, w# a* r8 c( S% N2 i
  1035.         }. \! t) A+ Q' n% E* F$ F
  1036. }
    6 S! k! x1 {/ S  u9 V

  1037. . J4 @- \9 z& ^% F9 M$ N3 i

  1038.   `4 ~1 u0 Y) T- O/ ?3 l; h
  1039. int main()
    ! H0 l, A3 F$ S! W) x7 L
  1040. {( Q. U- U, L( g' w, D. j* o2 _

  1041. 8 T" L* k( a4 c( e; S$ a* ^( _
  1042. return 0;
    * N4 Y& i( q* a! w+ s2 }- v2 o
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:1 w2 y8 [7 [3 i2 U5 k% [
   main()# ?; x1 {& J5 D4 G# t9 j7 N
   里面怎么是空的呢?
. N+ Q' h5 r% w+ `# N8 Z% R   发一份给我吧/ r9 H" s- [" \& S- h# Y+ E9 g1 O
mail:luyijun2005@hotmail.com
5 s2 d% ]' ?8 P# }8 H# k+ r5 B咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
4 c$ C! [7 _& F2 z" G2 a, A" ~8 X) k( {; _$ k
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
! r7 u8 T  l# g$ Z1 ?+ J$ M: Z. GEC的代码在哪跑,你看DS的说明,每个EC都不同的。5 j; J. b1 M% j; j& a  D
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?5 Y% q5 _" x6 M- v. w
上面几个问题是你没看任何东西而白问。( {8 H' I7 e  K. T1 P

1 a2 \  ?; O4 ~3 y, G至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。, [0 X. L' k0 }  \& p. R6 w
+ g# w8 n0 N. m  W2 F: L$ n6 H/ f# A
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
3 w6 T+ C  J. B2 c
: x& m0 ~5 X- u- h- T/ _关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
0 R  V* x, ?  ]+ y& S
- j9 s0 V; j( D* p: A关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊..." r4 _% b; a& Z

: M/ E# k! w5 [( t" x不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
+ H2 ]" c6 `7 k5 z似乎要把SPI能support 到最大,这EC chip应该有好卖点
; S/ Q1 y& u. r! s, h+ VBIOS功能要不要强大,也就决定了SPI Flach的大小: \/ S6 Q% _& i! L: q$ V
我是这么想的~让OEM去决定要挂多大!
. {: z& P8 F) t7 b! R如果我司有BIOS工程师就好了~哈% \4 S& p! T6 U6 g* f. {
WPCE775应该算很新的东西,来看它支持到多大?
/ z) |, ?1 V9 {$ [1 s$ {& A! Q0 P1 C  J! h3 \  S
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte, H( ?! w6 u& ]* ?
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
6 v# L, d  f" J& A3 x7 X3 E( a$ r- W
这份driver收下~希望以后有用到. x0 e: F8 ]8 F, T
谢谢bini大大* y& @1 t! @) g. D; G( b4 P
9 A0 a( m/ |& k5 ]  k* s' ^
很新很新的新手,如有错误请指正 (准备看第二家的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(): R( y4 K/ w/ m% k- u. z0 h& R* q
{
  T4 L' O! B, K        unsigned char temp = 0;% d, c5 K$ B4 F" D" s
        CE_Low();& A3 `* L) ]  G; D
    while (temp == 0x00)        /* waste time until not busy */
4 l6 N) Q1 t4 E                temp = SO;
8 C3 E( a& O2 p        CE_High();
) Z5 I2 n2 s  s) J3 ]6 f/ K}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
% N/ L& C# Z' U& b" K- ?3 `8 f( m{) D# x) {2 F- M# c7 N1 I
        
* {! \9 G; ]6 ^% m$ R7 B        unsigned char i = 0;
* m+ k7 v1 F/ U2 E/ b- j        for (i = 0; i < 8; i++)4 Z: Z$ w- h: g/ r6 D1 ~5 Y( K
        {- d; u3 ^% F( V5 V! A/ a: }
                - S6 |" `, e* o/ ~" ?6 H* c
                if ((out & 0x80) == 0x80)        /* check if MSB is high */8 I5 }4 m5 }- y. I4 Y/ s* F
                        SI = 1;
2 ?" \9 k1 m, a8 i7 [                else; K7 t1 O/ n: d/ R& a4 E
                        SI = 0;                                /* if not, set to low */
' e& _+ A' ~3 N6 k) ^) G6 Q. ?, ^- B 问              SCK = 1;                                /* toggle clock high */7 O6 Z/ f& r! h, x5 |  z
   题            out = (out << 1);                /* shift 1 place for next bit */
/ E, F9 R$ H% I9 f) c/ Y9 Z                SCK = 0;                                /* toggle clock low */
4 T1 ?4 F& y, O& y+ Y' @: }        }
- @( t5 ], {  X$ ?# V+ B8 E+ A}9 S; `+ B2 c% w5 z" g  N& K% t
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-12-1 07:15 , Processed in 0.084135 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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