找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55991|回复: 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
    3 s7 Q6 p9 J# C  y7 B* j9 F

  2. , ]  j2 J4 d0 ^7 i
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    6 _% @4 `/ }3 x
  4. & X# W9 ?: [' G
  5. November 4th, 2005, Rev. 1.0% j% p+ h& C# e
  6. % _! t6 C: ~( ^( z
  7. ABOUT THE SOFTWARE5 C& }* a8 w% z( K+ E
  8. This application note provides software driver examples for SST25VF080B,
    , s# F0 J- `0 F' }% G1 s; }. B
  9. Serial Flash. Extensive comments are included in each routine to describe   Q8 R) J/ D, z( K: i7 k5 H
  10. the function of each routine.  The interface coding uses polling method , \: p9 d/ k; \: A( r
  11. rather than the SPI protocol to interface with these serial devices.  The, E( O$ Q" W- b# z* [, O9 |& l
  12. functions are differentiated below in terms of the communication protocols2 N; _, s; ?2 g3 v& B
  13. (uses Mode 0) and specific device operation instructions. This code has been
    ( X; D% _: F$ A" f: Y
  14. designed to compile using the Keil compiler., A0 {1 l) k3 V, G1 D$ C5 B

  15. " G3 S$ x# N" M  G0 ]4 T$ f: T6 n

  16. 2 [! x! _/ }8 j8 L  n* G
  17. ABOUT THE SST25VF080B; r$ ]3 n: e$ W& F" s
  18. / v- ^, [  @3 M8 |  z
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    & ?3 h9 `1 v' C- {
  20. conjunction with this application note for a complete understanding : k. A6 |: b/ ^+ S8 Q, @
  21. of the device.* Z$ E; d( C) t5 h' P" s
  22. 6 T5 D5 J! }; o9 c; U1 D
  23. + J: k1 G( R( }% R4 |2 t
  24. Device Communication Protocol(pinout related) functions:  \2 ^! V3 X7 Q' O
  25. / h, s# z3 F$ M$ m9 z1 e3 L: ^
  26. Functions                                    Function( o) u) o; d# O) x+ f
  27. ------------------------------------------------------------------
    , i1 v' J+ Z" L$ t; Q
  28. init                                        Initializes clock to set up mode 0.
    0 G* l+ M5 U) m# \- H* j& C
  29. Send_Byte                                Sends one byte using SI pin to send and , n) e0 n) U' I. [
  30.                                                 shift out 1-bit per clock rising edge" X2 P2 z) n0 f1 _9 F! n  G. K' a
  31. Get_Byte                                Receives one byte using SO pin to receive and shift + d- T! |1 E4 P. q0 e
  32.                                                 in 1-bit per clock falling edge
    $ v6 C8 T" `( h2 |( v$ ?: {
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming9 Q3 @/ z, b0 ]
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high0 H: Y0 J0 ~) u" e# T1 O  ]" K* @( G
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    0 T! f" h9 v/ X& ]9 P$ i& c7 ~
  36. Hold_Low                                Clears Hold pin to make serial flash hold% Y# m$ T$ W9 I
  37. Unhold                                        Unholds the serial flash
    9 S7 U# v: Z$ D: `- Y5 H
  38. WP_Low                                        Clears WP pin to make serial flash write protected& E: j4 y, O) f
  39. UnWP                                        Disables write protection pin
    # l2 h1 l5 h. A$ L# f; b  e) E

  40. . W' w. {; f' i# I/ _* W  b
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code! E+ l2 W* w: C; G& t+ \
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your0 m+ f( m3 D' }8 v5 d
  43. software which should reflect your hardware interfaced.            X8 l, @, T$ \- S" r7 d

  44. ( P: x" j% i6 k

  45. & G& o. _. k/ R) B5 [
  46. Device Operation Instruction functions:, \/ t! y3 q' t6 W4 a" D; u
  47. ' R: Z# {! t: ?1 r7 C- @: M  B1 Z
  48. Functions                                    Function# [& Z/ i4 p; r: V8 i; [
  49. ------------------------------------------------------------------# g9 |" \. U0 ], E1 [, E
  50. Read_Status_Register        Reads the status register of the serial flash$ G$ J- v' Z/ x9 ]4 R# D$ `
  51. EWSR                                        Enables the Write Status Register1 @3 i. c* j1 n) n8 T2 Y) P( o& c
  52. WRSR                                        Performs a write to the status register! \+ ~8 l/ d* C; h& j
  53. WREN                                        Write enables the serial flash
    * a# J0 Y% [: u4 Y
  54. WRDI                                        Write disables the serial flash
    - h0 K3 H- _; R+ r/ Z( Y
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming# Y$ l' N5 Y5 V9 }' h4 v( h
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    , s& g. l7 i. a; ^- e# `( t. I, X
  57. Read_ID                                        Reads the manufacturer ID and device ID
    ' O. @& L+ ~& t; V! z  Q8 `
  58. Jedec_ID_Read                        Reads the Jedec ID1 ]* j6 q3 j5 h  }' I1 h
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)& Y, r4 w8 B) j/ A# |0 |3 F
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)! R, |- ]4 B# P( `7 K8 f
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)4 ]8 S& t7 f- L% l1 C; Q, f. n3 C6 h
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)  c! w  G2 d/ n% F: z+ H
  63. Byte_Program                        Program one byte to the serial flash* L' L, ?5 N9 N# Y. x' ^+ ?2 W
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    - |6 }) q% y4 p3 |+ Z
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    6 @1 v" p1 Z" B5 j
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    + P% ?) P! K8 {$ f# p
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY* n: g& n' v2 Y) m) A7 f
  68. Chip_Erase                                Erases entire serial flash
    * [2 P+ h/ L2 }. B: `
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash0 F$ a# N9 D6 L9 T( k1 {
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    ' `$ f2 W1 Q& ]) J
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash4 a: Y% [' ?. B3 {
  72. Wait_Busy                                Polls status register until busy bit is low" B: M* l+ Y* o: a  V
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming' o1 K% u$ u$ X" p- l
  74. WREN_Check                                Checks to see if WEL is set
    # I6 M: ~/ Q2 g. [' t; u% X% Z/ L
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    7 W' U5 i, |" L2 @

  76. % U! i9 I- ?, ^4 _$ B5 H4 J; A0 W- }& |
  77. & L9 e8 P* t, q8 D. P9 b# b
  78. 7 h$ K& j3 Q% c- Z3 l" T) Y
  79.                                                                      , h% g5 \* f! O% X, g6 B
  80. "C" LANGUAGE DRIVERS 0 G$ F: N, L( P! R1 h
  81. 5 p' |& X1 a% Z6 n3 ?
  82. /********************************************************************/& x/ a8 C/ P" H6 Q$ U  j4 w
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */" S' e2 }3 N' z& b$ S$ o
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */, l& o1 ~5 {# ]4 P3 v; |3 @
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */- T  m9 \* A) O7 W& [$ M
  86. /*                                                                  */5 D; w) h5 G1 o2 e4 v9 y$ V2 g
  87. /* Revision 1.0, November 4th, 2005                                                                          */   1 }# A" d$ \* y" }: L: Y2 D
  88. /*                                                                  */
    0 \" o( G4 |# r6 J
  89. /*                                                                                                                                        */$ [# W0 G; d  l- K. K0 v
  90. /********************************************************************/
    5 O1 g! C' v' V4 n

  91. $ |5 s4 a& p' Z( `8 k- |; y
  92. #include <stdio.h>1 N) {! U5 C6 i+ B' i  v* P% J
  93. #include <stdlib.h>
    * `) p$ ?4 p  \. f' Y/ |% Q/ m

  94. * F/ v2 D$ L' H* |' p
  95. /* Function Prototypes */' \0 A, c* T! l% V; S

  96. 1 U4 l' S3 r) B% Q% o1 R' O; ~
  97. void init();( l/ d" R1 N1 e$ a# v& _: R: O! |
  98. void Send_Byte(unsigned char out);
    0 F! b6 Q& D7 \+ V2 ]$ G# u( s
  99. unsigned char Get_Byte();
    . Z  w4 N% n; l
  100. void Poll_SO();3 O8 |+ e7 A3 V3 h$ g9 a5 h% A* v7 ~
  101. void CE_High();
    & L8 g4 A; c3 R$ R6 I
  102. void CE_Low();7 Y8 O, s4 G& y
  103. void Hold_Low();4 m' q( ~3 x$ _0 ^
  104. void Unhold();
    ' ^6 z9 \5 ]. D2 A1 W/ G, }: v
  105. void WP_Low();
    ) s+ r) J9 E% C0 D( m7 D
  106. void UnWP();( s! {: w$ u' r" N
  107. unsigned char Read_Status_Register();; b, r2 a9 `3 p
  108. void EWSR();
    3 ~6 T, p' V$ {/ i
  109. void WRSR(byte);* \, K0 L' _  `$ e2 \/ \: a; k
  110. void WREN();% P" [7 ?& O0 Q' _! I
  111. void WRDI();
    4 c* ?: r) N% D* D4 E
  112. void EBSY();* R  q; k6 L1 U2 \
  113. void DBSY();
    " M1 x7 r) O5 u
  114. unsigned char Read_ID(ID_addr);& @( H  t: m  I9 {' O. s- i
  115. unsigned long Jedec_ID_Read(); ) P( y2 U5 M! y) \- C4 J
  116. unsigned char Read(unsigned long Dst);
    1 M# v9 q; H, q% z; j# h
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);; p, o& O2 m4 W. b, s) g6 |
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    ; n, r% m8 F+ |* S, A3 m2 U
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    , s. N  a) \: R0 U- X
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    ; N$ X) H* N  a0 F
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    : z1 M& V: w0 [1 n# U/ H
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);8 x. u7 K1 r2 F8 Q; f$ k
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);0 ?: q  M  ~7 k/ q
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    $ `# {0 ]( r5 _; p! U6 c7 q$ C# l
  125. void Chip_Erase();1 n' J3 @  d3 a
  126. void Sector_Erase(unsigned long Dst);
    8 Y2 P0 s( p) Y2 O/ I3 m3 x
  127. void Block_Erase_32K(unsigned long Dst);' t+ y5 M2 Y8 f
  128. void Block_Erase_64K(unsigned long Dst);
    1 m0 M2 }8 \) `* F, s: `. |
  129. void Wait_Busy();
    4 @% v& {* _1 c2 P+ T* A) \) I
  130. void Wait_Busy_AAI();
    % Q# b1 \+ x' Z1 l! Z
  131. void WREN_Check();
    + H6 l6 j  s  z2 j% Y0 f, j" F
  132. void WREN_AAI_Check();9 U! ]6 |2 y6 S3 @9 j) m
  133. / q4 P& `; o* p
  134. void Verify(unsigned char byte, unsigned char cor_byte);3 l4 R! v, F* {2 U

  135. $ [/ D( J% S7 {) R  [( n, ^
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    3 [  u; D% \* i2 G
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    ' l" O2 v' [, K, z6 g  G
  138.   f- M8 x8 p( t! a- [$ F
  139. /************************************************************************/
    8 W: ^4 E" U5 ~8 @
  140. /* PROCEDURE: init                                                                                                                */
    # P8 G& ~) v# D7 p0 c
  141. /*                                                                                                                                                */
    7 w2 g! E9 L* {) \
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    * L+ m/ S3 s( U7 y: @2 J, I' @1 _
  143. /* setting up mode 0.                                                                                                        */
    9 E# u  g' Q* V- H% P/ R
  144. /*                                                                                                                                                */
    7 y6 B4 H4 e4 }4 ]! [
  145. /* Input:                                                                                                                                */% p8 G; @$ i: o% x
  146. /*                None                                                                                                                        */
    % W+ M. N; _, g& g) G
  147. /*                                                                                                                                                */
    , S" B8 `. Y, Z+ Q
  148. /* Output:                                                                                                                                */1 P2 P+ k. ?1 L+ `- K# y1 A9 z8 N
  149. /*                SCK                                                                                                                                */, q2 K' ^( R6 c# j2 B( M
  150. /************************************************************************/, w  G' T, m9 D+ F& ^
  151. void init()
    % U6 X; M5 g7 d/ M7 o3 {" T
  152. {+ \9 Y$ A3 u: U$ \3 Z& P
  153.         SCK = 0;        /* set clock to low initial state */& B1 G/ j% S4 h% q2 ^
  154. }
    ; A0 o, M8 q+ i0 p

  155. + G" v2 \  d' W4 n6 D
  156. /************************************************************************/& o4 S2 x! x9 T
  157. /* PROCEDURE: Send_Byte                                                                                                        */; r0 O+ V; D" @
  158. /*                                                                                                                                                */( l9 f2 {9 }1 I3 [9 F% O/ j* K
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    4 H4 L, O) \& _- K$ A
  160. /* edge on the the SI pin(LSB 1st).                                                                                */+ o; k8 G& Z( s! j# x
  161. /*                                                                                                                                                */
    & V4 m- o6 i$ g; I# F
  162. /* Input:                                                                                                                                */& N& \; W8 K% A5 A% G
  163. /*                out                                                                                                                                */7 T6 p+ _: T7 M
  164. /*                                                                                                                                                */
    - ^! S7 r9 y7 C: h0 k, g% c, ^
  165. /* Output:                                                                                                                                */
    4 I8 o7 }& N, h( q& ^5 W
  166. /*                SI                                                                                                                                */: m5 K4 T( a1 U- {
  167. /************************************************************************/, I% v# Z8 e& I  e1 N
  168. void Send_Byte(unsigned char out). p$ V) A. z! j( c2 x( z
  169. {# e* _: k, N5 [7 ]; z/ z  R
  170.         & q& h6 {4 N* A6 W1 t
  171.         unsigned char i = 0;
    9 C3 y: M: E5 J! m7 |
  172.         for (i = 0; i < 8; i++)6 h: F5 _: q) S! f; D% [! D
  173.         {; g' Y) q+ \. e$ H4 P1 G0 L$ Y
  174.                
    4 ^3 d% ?- P# n# J" }. P% U
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */2 }* F  f6 B/ k; G
  176.                         SI = 1;
    ! C7 G9 O1 }8 Y! |- Y- w
  177.                 else
    1 ]1 `4 p* }0 `% F" b" n" Z8 }
  178.                         SI = 0;                                /* if not, set to low */0 Q. K3 L. c' J' F7 O3 y( {
  179.                 SCK = 1;                                /* toggle clock high */+ q* r& u: n" E. u6 r- N. h
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    2 w3 g6 U* K5 j6 U
  181.                 SCK = 0;                                /* toggle clock low */
    ; Z0 l4 `" Q1 O8 i& i4 |
  182.         }
    6 i1 Y) H9 L! i. Y$ a+ K  ], J
  183. }
    ( R2 e1 i3 l& r/ x6 S# T5 E, @
  184. * B8 @* }! A/ h; j8 m
  185. /************************************************************************/
    9 I% J+ n: h- K! k
  186. /* PROCEDURE: Get_Byte                                                                                                        */  N% N  d. ]) [
  187. /*                                                                                                                                                */
    9 F' f6 \5 {* E
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */  C1 d+ x5 a/ ^0 n
  189. /* edge on the SO pin(LSB 1st).                                                                                        *// a/ k4 Z% M0 M5 _
  190. /*                                                                                                                                                */+ ], }- x- `# }/ N& t
  191. /* Input:                                                                                                                                */
    # |9 |9 H$ e, r; H; Q' a
  192. /*                SO                                                                                                                                */$ ?  n$ ?+ s. F" l/ f; q& o& H
  193. /*                                                                                                                                                */
    ' q& |- D  s) _+ ]- T/ c  T
  194. /* Output:                                                                                                                                */
    , a% u) y3 h6 L7 S% \2 ~; Q: x  B
  195. /*                None                                                                                                                        */+ w! c9 l* K8 U/ H, v" d1 v7 u4 c
  196. /************************************************************************/
    / T. U- ?1 G8 @% Q( @+ F0 a! r
  197. unsigned char Get_Byte()
    4 C! r! J* P) U7 P6 l% a- H/ S
  198. {
    & H3 X' |% _% U! ?
  199.         unsigned char i = 0, in = 0, temp = 0;
    5 _; H- A& \+ g+ _
  200.         for (i = 0; i < 8; i++)* M" A0 l' o  ^# ?, L
  201.         {, H6 j2 |" U8 z, H# N" H, r& l" `3 n
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    / v$ o8 D- \7 _5 D3 l5 F9 H0 U
  203.                 temp = SO;                        /* save input */+ v" K8 J* X/ r0 x& D5 x0 O
  204.                 SCK = 1;                        /* toggle clock high */
    % R! V. h/ `( B# J6 y1 L. i, q
  205.                 if (temp == 1)                        /* check to see if bit is high */
    . H3 {& l1 b* E: w) P( c% @
  206.                         in = in | 0x01;                /* if high, make bit high */
    % o3 T( a) z4 u) s% H2 f! n) l
  207. # [# m) v6 d; h$ A9 w) W
  208.                 SCK = 0;                        /* toggle clock low */! o+ r( H: n! @; p

  209. : e+ I4 e, ]+ U
  210.         }5 R- X( k. C* i: d0 S( Z( M
  211.         return in;4 g$ W3 ?. E8 r, t% L
  212. }2 U8 q' ?' Z- @1 a$ F
  213. & [% k9 J* A7 Q4 [5 ~
  214. /************************************************************************/
    " G* h1 y- |5 O
  215. /* PROCEDURE: Poll_SO                                                                                                        */7 t3 w$ Y' t5 C" ^+ y0 _! F+ T2 n
  216. /*                                                                                                                                                */
    - J8 b( R6 B/ t
  217. /* This procedure polls for the SO line during AAI programming                  */
    7 V" }8 O& [( k  I. e7 ^" F# C# q
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/0 X' o/ t& v* [+ r" l
  219. /* is completed                                                                                                                        */8 K( N' Y' Y6 a5 y9 d, i
  220. /*                                                                                                                                                */
    8 u! Z) d5 e+ s2 M  Q# Z/ I; _
  221. /* Input:                                                                                                                                */0 ~0 T. n# g' t4 M6 I3 W" [
  222. /*                SO                                                                                                                                */6 r: l9 \% X4 K1 `: Y, D# ~+ G3 P$ O
  223. /*                                                                                                                                                */% e- J# u$ x2 @! e
  224. /* Output:                                                                                                                                */
    % x( E2 O1 u! ^2 P
  225. /*                None                                                                                                                        */  Q8 q, \7 b4 z; z  g
  226. /************************************************************************/: f" M" q# L3 h+ t. B+ e
  227. void Poll_SO()
    4 A8 \' \! y! b' m  V
  228. {
    2 H: J( }6 ?: _: x
  229.         unsigned char temp = 0;1 C  s$ `; U* [: y+ `
  230.         CE_Low();- f; t* y. h0 s6 W' P" K
  231.     while (temp == 0x00)        /* waste time until not busy */
    # U6 a, F5 i  v. q# Y5 b" j
  232.                 temp = SO;- Z+ c! c( c& D
  233.         CE_High();& E! G$ b# O/ u1 q( V1 _( @; I
  234. }
    ; _; u5 |/ l. }
  235. " x" u5 g& P( H3 w9 ]
  236. /************************************************************************/1 j) E3 H2 i. }/ m! @+ D7 [- n5 T
  237. /* PROCEDURE: CE_High                                                                                                        */3 B! Y. r! l' C5 s, _
  238. /*                                                                                                                                                */9 g) P' B0 K8 Y+ n
  239. /* This procedure set CE = High.                                                                                */
    # n2 Y) {5 m5 W# }9 z) N9 [
  240. /*                                                                                                                                                */
    + r/ m, W9 P; ]  w/ A9 Z" m( ~
  241. /* Input:                                                                                                                                */
    * Z4 Z2 _: U8 H1 ]8 x0 I
  242. /*                None                                                                                                                        */  i' o  I; x( L; @* f4 |8 I! y
  243. /*                                                                                                                                                */
    ( R# R3 A) J  ~  a* }% u0 ~8 S! X
  244. /* Output:                                                                                                                                */
    7 E$ E. m/ i: Y' e& t
  245. /*                CE                                                                                                                                */) K. j* |8 b6 ~& w& v- q- h
  246. /*                                                                                                                                                */
    . g1 D' \9 L. i8 a
  247. /************************************************************************/
    8 S! m* u+ w1 k1 ?$ S
  248. void CE_High()
    / k+ d6 d" i: B
  249. {& X6 I9 J: l  @9 H, W1 X5 I
  250.         CE = 1;                                /* set CE high */7 T/ y7 M* _7 [* D
  251. }
      e' u( @& X2 j+ a
  252. ' ]0 p) V; ]3 X" h* g5 }( J
  253. /************************************************************************/. [& l1 H9 H' Y* m) z# L
  254. /* PROCEDURE: CE_Low                                                                                                        */% b5 E; d% h( R" E# s1 h; k
  255. /*                                                                                                                                                */
    " ]! d# u3 G) o, n  {
  256. /* This procedure drives the CE of the device to low.                                          */
    9 F+ o3 J# e: Q& e% d, i' Y8 {  D
  257. /*                                                                                                                                                */6 ]; q6 C% S3 ?+ p; r5 _8 m" q; G
  258. /* Input:                                                                                                                                */: p; n" v) p5 k$ K8 V% A
  259. /*                None                                                                                                                        */% t* L8 Y, p4 \- B4 ^% }3 j
  260. /*                                                                                                                                                */
    " X: ^6 T4 V# ~5 S$ y; j
  261. /* Output:                                                                                                                                */8 p, m0 d' {$ ]* A/ \
  262. /*                CE                                                                                                                                */! i" {/ Y" M* m. ]% i) H8 b1 h
  263. /*                                                                                                                                                */" _5 E6 Q0 |+ J7 H  u0 B! W( U: A
  264. /************************************************************************/# W, F  h7 w& M4 M6 I6 I
  265. void CE_Low()
    8 f9 Y2 ?+ x! H
  266. {       
    & ^+ Z( T* K6 a; O: C
  267.         CE = 0;                                /* clear CE low */2 l% b& V/ J* o2 q8 Q
  268. }9 ~: S2 z6 v2 W: U2 ~( t3 @! R; n: g
  269. , D! |6 \- Y9 I. c1 U6 T
  270. /************************************************************************/  f; |7 \# w" r# `& S
  271. /* PROCEDURE: Hold()                                                                                                        */
    9 y$ T; A: |# R$ O0 q- a* u. D1 V
  272. /*                                                                                                                                                */
    7 w  a$ Q: O7 B' T: m1 k
  273. /* This procedure clears the Hold pin to low.                                                        */
    & l; Y9 F  e3 l9 _/ v
  274. /*                                                                                                                                                */
    8 ]; t3 x( X' k! L) w2 J
  275. /* Input:                                                                                                                                */
    4 z. K( X% ~6 f+ u! r! q( o8 z
  276. /*                None                                                                                                                        */
    ( `+ C2 T* r/ F. O4 I; M- z/ W
  277. /*                                                                                                                                                */
    : d0 K- F7 N+ Y$ E  Q
  278. /* Output:                                                                                                                                */
    % x0 K4 ^$ j' o3 Y; u% \0 m4 K. O
  279. /*                Hold                                                                                                                        */
    " {6 Y2 w4 A3 z3 m
  280. /************************************************************************/1 _* d4 ~  }% |+ G- V% M9 k
  281. void Hold_Low()2 w& d- y$ X7 U# a1 I
  282. {
    0 B) k+ J" F& i0 u+ \
  283.         Hold = 0;                        /* clear Hold pin */8 x7 A& y' e. r. C6 w! E7 `
  284. }2 A( k8 q9 l6 N: @- [
  285. : ~. b; Z) o! c- X! F2 s! r
  286. /************************************************************************/
    9 y0 \' r7 @4 X, o
  287. /* PROCEDURE: Unhold()                                                                                                        */
    6 k; V  I9 C6 ]+ F" M
  288. /*                                                                                                                                                */" z& W8 n# m) p& h  N! m
  289. /* This procedure sets the Hold pin to high.                                                        */' [- c/ }9 Q* q$ S
  290. /*                                                                                                                                                */5 _5 R5 b; n* `% O/ E
  291. /* Input:                                                                                                                                */# P' ?, r  Z+ }
  292. /*                None                                                                                                                        */
    * D" l& Q" U* ^9 H+ Y
  293. /*                                                                                                                                                */5 q4 @3 ~1 n' e; I7 K
  294. /* Output:                                                                                                                                */
    9 B3 m" q6 _6 o( ?8 O
  295. /*                Hold                                                                                                                        */; j) x) S+ d; r
  296. /************************************************************************/
    * n1 Q. V6 o! J5 O0 l6 G
  297. void Unhold()
    1 F( T6 b3 Q, J" D! X: d' W: l! L
  298. {6 J5 l$ d+ l8 \% D
  299.         Hold = 1;                        /* set Hold pin */
    5 `; \3 t# e& s
  300. }: R) ~2 F0 l# |( |

  301. " w4 B9 F# X0 j" B1 y+ N: A+ o
  302. /************************************************************************/; _' M: L- T6 C7 q* t. x! V1 y: q
  303. /* PROCEDURE: WP()                                                                                                                */0 @% D: f( A6 O
  304. /*                                                                                                                                                */
    ; }- S! Z( C+ V2 v0 C
  305. /* This procedure clears the WP pin to low.                                                                */
    3 J5 l8 M- D0 V0 k1 {( Y6 H. H
  306. /*                                                                                                                                                */
    / p3 q! q9 Y9 }9 M9 N4 {4 y
  307. /* Input:                                                                                                                                */& E0 K. P2 b9 C/ f% z) h1 P/ x
  308. /*                None                                                                                                                        */
    ) e# [- A7 V" E" ]; Z5 I5 e" t
  309. /*                                                                                                                                                */
    * C& V. Q! @: C9 i8 u1 i
  310. /* Output:                                                                                                                                */
    3 `* Q3 g. C; q, `2 `( p6 B7 K8 j
  311. /*                WP                                                                                                                                */- c- ?4 I$ B3 m5 W
  312. /************************************************************************/
    0 M* b% g7 G7 }6 c7 m8 H9 x. o
  313. void WP_Low()9 F1 F* T, [8 l; s# G
  314. {
    3 u! O+ M3 z6 i5 n+ _
  315.         WP = 0;                                /* clear WP pin */
      E6 }6 r. R4 ]5 q! t
  316. }
    2 ~6 n$ e, h0 M: l$ V" R( D& ^8 ?8 }6 t

  317. 1 h  g! Q/ g, S. m- r5 \0 S/ E( G
  318. /************************************************************************/
    7 n% A; D$ s2 L  G5 b
  319. /* PROCEDURE: UnWP()                                                                                                        */
    7 A* H' a) n! D7 A. \# g& ^2 A
  320. /*                                                                                                                                                */) J/ g' j6 {7 K4 N+ Y
  321. /* This procedure sets the WP pin to high.                                                                */1 |" ?" [) c' t8 F2 [
  322. /*                                                                                                                                                */
    + U. K- ]1 J& I& I4 z
  323. /* Input:                                                                                                                                */
    7 A. o: |; ?1 H7 B" k
  324. /*                None                                                                                                                        */: u( z$ G( b" u# t
  325. /*                                                                                                                                                */
    . M" q8 W. P% Q7 P
  326. /* Output:                                                                                                                                */
    / O  t+ b2 p0 h& Z) H
  327. /*                WP                                                                                                                                */3 v+ U2 z  G& l+ U0 n: u9 S1 O
  328. /************************************************************************/( N7 h  W, |9 O8 P4 f4 H! u
  329. void UnWP()
    + J, b8 n6 I! q
  330. {1 s0 ^6 F- L5 o9 X
  331.         WP = 1;                                /* set WP pin */6 u% L9 ]  Q3 O" g" f$ s
  332. }
    / K- k( E+ X: Q) F

  333. ( U2 U* k5 Q* o( o
  334. /************************************************************************/; ]7 O3 ^3 C, K  q. ^
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    6 d; W' {" t( b4 }
  336. /*                                                                                                                                                *// J; B7 i; }% M' X2 g
  337. /* This procedure read the status register and returns the byte.                */1 i1 O/ H% J- H! `/ A/ o$ F; M
  338. /*                                                                                                                                                */- f, g% A/ I( V5 [$ V* D4 r
  339. /* Input:                                                                                                                                */
    # u0 m4 {! z- S$ a  Q5 U/ Y3 \
  340. /*                None                                                                                                                        */
    * a3 j' Q" \& x* [/ a0 w' Z
  341. /*                                                                                                                                                */9 ]9 V4 ?9 u3 e
  342. /* Returns:                                                                                                                                */
    2 s+ ]0 D+ b6 t4 ^( ^
  343. /*                byte                                                                                                                        */
    . Q, J9 Y0 L3 v7 U
  344. /************************************************************************/, i, H1 J% Q5 k- C6 ]7 }
  345. unsigned char Read_Status_Register()& O; ~, U" x( `" @( P
  346. {6 Z8 h, @/ w/ r5 g
  347.         unsigned char byte = 0;4 C( K# a) O# \" @/ k# s; S
  348.         CE_Low();                                /* enable device */
    $ E' V; T! z" t3 ^% h* J# G
  349.         Send_Byte(0x05);                /* send RDSR command */
    5 [# U, T3 j- ]7 R1 T3 t7 Y' i) q
  350.         byte = Get_Byte();                /* receive byte */
    - {8 h. y8 M! y3 J$ J& q1 ~
  351.         CE_High();                                /* disable device */. R- w/ X8 H* _5 h
  352.         return byte;7 U$ ~% @' n; ^2 _, y. o3 [
  353. }
    # }- ~' Z* A( t
  354. / x4 ?% G6 j. {+ h- x* @0 ]5 _
  355. /************************************************************************/
    3 X  P, M( J& Y
  356. /* PROCEDURE: EWSR                                                                                                                */# T5 f2 E/ v4 \6 V* L4 \5 D
  357. /*                                                                                                                                                */% c" {; k1 [) e1 t
  358. /* This procedure Enables Write Status Register.                                                  */
    $ }( h% f' W$ {  H' E$ _8 |2 ~
  359. /*                                                                                                                                                */( @' f# u1 _  t; a: c% Y
  360. /* Input:                                                                                                                                */
    4 d7 k1 i# o' l" r3 G
  361. /*                None                                                                                                                        */% r/ {% h9 n: L
  362. /*                                                                                                                                                */+ y( h- L; e# J
  363. /* Returns:                                                                                                                                */4 q" s' V6 R8 H+ @6 U2 W8 J
  364. /*                Nothing                                                                                                                        */0 z$ ^$ i# P1 g( m3 K
  365. /************************************************************************/1 l# s. J9 i6 K9 ]4 D
  366. void EWSR()$ x# n, X9 c# ^9 N
  367. {% m( F" B! `  F) ?# t1 V0 Z- r7 J
  368.         CE_Low();                                /* enable device */6 _4 R% r& W4 T' Y% P+ @1 X+ j
  369.         Send_Byte(0x50);                /* enable writing to the status register */  |& Q5 J' Z1 a% L
  370.         CE_High();                                /* disable device */
    - G$ o% }( d: X5 E
  371. }( Y6 \/ l4 e6 C( Y" @) n0 n4 `6 O

  372. , Z9 v, i+ J  o' k& K; `5 x
  373. /************************************************************************/
    ' P+ S; @! [8 l6 h1 |/ a! J. \
  374. /* PROCEDURE: WRSR                                                                                                                */
    : I$ _! @& z: J+ p2 U: d" H3 R
  375. /*                                                                                                                                                */* |* H# D5 x# T) E6 s* j
  376. /* This procedure writes a byte to the Status Register.                                        */
    , ~- x+ M% \5 M, N3 `# H0 R
  377. /*                                                                                                                                                */
    ( E; D! b2 f4 }) \' Y# @
  378. /* Input:                                                                                                                                */9 E9 ~% U& w+ L" N) d$ _7 O; v
  379. /*                byte                                                                                                                        */: Q5 i8 Y0 C: Z" w2 O, @; n" a+ z
  380. /*                                                                                                                                                */
    $ Z1 U) H$ \$ z6 E! Q1 b3 J( J+ g" j
  381. /* Returns:                                                                                                                                */) t: x( w8 t) w; x. `
  382. /*                Nothing                                                                                                                        */
    8 _, i$ _1 A# ^, s8 W* g
  383. /************************************************************************/
    1 l( L9 u' Y  U" P, `  i: ?( F
  384. void WRSR(byte)
    9 }5 T- P: w; X( [
  385. {
    4 p) l' X" R& Y- r) s" s% Z. Y
  386.         CE_Low();                                /* enable device */
    0 Q* d: [6 x  `& D
  387.         Send_Byte(0x01);                /* select write to status register */
    . b4 l( K6 [" l+ d  F1 l7 X
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    9 @4 Q. u- }, f) W" o! a, |
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    6 W- X6 {0 U: q& H4 @- }5 C. [6 H' o
  390.         CE_High();                                /* disable the device */
    7 [5 b; X& a* Z# P; ]  V
  391. }, \5 o4 i1 X9 `, h) M( W/ ^- P
  392. $ `( R  `8 {3 P8 l4 l
  393. /************************************************************************/
    ; N/ A( u0 x1 f
  394. /* PROCEDURE: WREN                                                                                                                */" }( ^' |8 `3 r3 p/ ~2 P2 ^
  395. /*                                                                                                                                                */! G. \' l' W- [, \( `
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */8 a7 ^2 W( ^5 G0 z
  397. /* to Enables Write Status Register.                                                                        */' k- Q# T% R* T& t$ l) ?( q/ V  E/ L
  398. /*                                                                                                                                                */
    , b0 x  f' I+ K2 L: a
  399. /* Input:                                                                                                                                */
    . h7 K5 `2 D1 _# I& e6 ^  `
  400. /*                None                                                                                                                        */
    1 Q; ?; M* v1 x3 l2 A- s3 U
  401. /*                                                                                                                                                */+ v! O5 h; k& E/ N6 z
  402. /* Returns:                                                                                                                                */
    7 [1 ^6 y+ h$ g
  403. /*                Nothing                                                                                                                        */
    " P* B5 P+ ?+ a6 d
  404. /************************************************************************/
    " m& _; ~* A% Y) H
  405. void WREN()+ Q$ @- E0 Q( s6 N4 ?
  406. {
    2 P. Q! h" g8 D" d: l! o, I0 r
  407.         CE_Low();                                /* enable device */
    " @: C. T0 o! ^$ V1 [$ {
  408.         Send_Byte(0x06);                /* send WREN command */
    . w" v0 @1 H! N, ^7 R' A2 I; h
  409.         CE_High();                                /* disable device */
    . u1 D9 p3 \2 o) }
  410. }2 v( P% X$ k" O& H4 h

  411. . [( C+ R8 K* e# Z+ p3 ]  K* I
  412. /************************************************************************/( l$ d3 f+ @1 M% M- D
  413. /* PROCEDURE: WRDI                                                                                                                */; B' O  X" y: f7 J, e/ v
  414. /*                                                                                                                                                */' ]4 y8 c0 l! X( E% F) F
  415. /* This procedure disables the Write Enable Latch.                                                *// f- [& B% Y6 P1 Z8 M4 X) }* Z/ e
  416. /*                                                                                                                                                */
      l# X5 }# d4 d! a8 \  b0 F
  417. /* Input:                                                                                                                                */
    0 i& p6 }$ Z( Q: u: L
  418. /*                None                                                                                                                        */+ t8 \0 F( V2 m4 |
  419. /*                                                                                                                                                */. G2 |+ [: c  w& e- H( i0 Q
  420. /* Returns:                                                                                                                                */: A! i; A) g; w$ y+ F: ^
  421. /*                Nothing                                                                                                                        */3 P8 x- b" X  L1 A: c3 `- c+ S" a
  422. /************************************************************************/7 j+ N0 q$ S3 X$ f$ {3 {" I
  423. void WRDI()
    3 l1 ~/ K$ o- I2 R1 q
  424. {
    ( ^. W/ j8 a$ ^) I+ C, y7 |
  425.         CE_Low();                                /* enable device */4 \( B4 t9 X( o' B3 a6 e
  426.         Send_Byte(0x04);                /* send WRDI command */" T# @' r7 _" z' K3 q) x
  427.         CE_High();                                /* disable device */
    ' W( D; a/ v& Y6 |+ G; v+ S# z- C
  428. }0 a) h8 A( L0 w$ I
  429.   d! t8 P: D+ [, K( `9 |! g
  430. /************************************************************************/
    / w7 J, [3 K# R6 r$ V1 G
  431. /* PROCEDURE: EBSY                                                                                                                */5 J& |! E2 U% d- b0 e* j/ S- a
  432. /*                                                                                                                                                */
    / w, i7 T6 l5 B" ?& p: z; X
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    7 m1 I6 J* S) [) E8 l/ C
  434. /* programming.                                                                                                                        */
    - ?$ U2 X6 ]5 z% f9 m& c6 ^; |  `
  435. /*                                                                                                                                                */
    ( q2 p7 W" U' G, L4 S, j
  436. /* Input:                                                                                                                                */
    - R7 K/ L  K  }  O7 c. ?* Q0 U1 H$ m
  437. /*                None                                                                                                                        */2 ?+ o/ w3 |1 Q8 o( }
  438. /*                                                                                                                                                */
    % m( Y+ T8 Z! Y" g1 j
  439. /* Returns:                                                                                                                                */
    5 D) ^7 `6 v# G8 Y
  440. /*                Nothing                                                                                                                        */( f  |% \( Q2 i$ A4 _1 S# m
  441. /************************************************************************/
    : ]9 b( G! R* z. y& L4 c
  442. void EBSY()8 @1 B( d3 D1 b; t1 f( c
  443. {
    $ ^3 P9 B! u5 E( P* U- I5 P: W
  444.         CE_Low();                                /* enable device */3 R! h2 k  N) k
  445.         Send_Byte(0x70);                /* send EBSY command */7 `; S( }. A; X) B: Z: O; g
  446.         CE_High();                                /* disable device */
    % L% c/ o% G! ^1 Q; }6 v+ e
  447. }9 S. Y" A; Z  C+ \$ W! X- ^
  448. / k2 d9 y* i( Y7 p
  449. /************************************************************************/7 r" T! ?1 q6 g  i/ v
  450. /* PROCEDURE: DBSY                                                                                                                */
    0 v8 i: s  P) B- {6 G8 R* H
  451. /*                                                                                                                                                */
    ' ~7 @2 b9 ^" b/ R4 _
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */2 b. t8 W% l8 A9 I
  453. /* programming.                                                                                                                        */' E# ~9 @# F* p
  454. /*                                                                                                                                                */
    4 t7 Q8 W; ]: X3 @. ~7 V' L" T
  455. /* Input:                                                                                                                                */
    ' V/ f. Q5 N9 U
  456. /*                None                                                                                                                        */, d& Y6 [! J8 y9 X$ A6 b
  457. /*                                                                                                                                                */- C% f- I1 s  Z$ @
  458. /* Returns:                                                                                                                                */" Z* H7 {" v# S' Z  i9 C* C2 Y# ]
  459. /*                Nothing                                                                                                                        */  m; l7 L& D. ]* [
  460. /************************************************************************/( |; d" T4 D$ S5 f+ H0 d1 k
  461. void DBSY()# o6 d' g; k4 y1 z
  462. {: z, S" s7 {! ]. ?" y' w5 c
  463.         CE_Low();                                /* enable device */
    7 B2 E* i) E+ a8 s) |' s3 R( t/ Z
  464.         Send_Byte(0x80);                /* send DBSY command */6 c+ n4 L) H+ A5 H3 _4 V+ V
  465.         CE_High();                                /* disable device */) T' x# Q1 F& J; L: L
  466. }
    ; O3 U/ T, z  D( F# E
  467. 9 O$ j/ f9 X  X: {$ X
  468. /************************************************************************/
    1 x/ S- i! \9 b6 ~2 \# u
  469. /* PROCEDURE: Read_ID                                                                                                        */
    % r& b* N) a! E9 D1 G# d9 T( y8 n
  470. /*                                                                                                                                                */
    - \- H$ q9 }1 }6 u7 `' l
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    . q0 F3 o4 U3 L4 r9 ?7 B
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    ( v6 U$ q+ j) L: x) n$ F( v
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    1 N4 J$ H* t6 ~% h, T+ X( |7 M
  474. /* whether the device outputs manufacturer's ID first, or device ID         *// I' S% W$ {, u  t2 W- e
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    ( p- {- H$ {6 t: f, v
  476. /* variable byte.                                                                                                                */9 [" c* W' }9 v/ d
  477. /*                                                                                                                                                */, |) ^. W5 W: F0 P" Q
  478. /* Input:                                                                                                                                */9 S/ \$ p9 ]0 o, Z: o+ [( o. }
  479. /*                ID_addr                                                                                                                        */
    4 B' O; Q! T; O3 T+ m) @
  480. /*                                                                                                                                                */
    , b" g% S/ K7 \' q- \
  481. /* Returns:                                                                                                                                */
    0 N9 v  z) }) @" X! ^
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */, _! Q( z5 Q* W
  483. /*                                                                                                                                                */
    7 A9 z9 Z0 T6 ]2 s# _+ }# D
  484. /************************************************************************/7 _! X" k& j# w' B4 f; A
  485. unsigned char Read_ID(ID_addr)
    ) o, `4 X& B. ~  s
  486. {8 {% j! {' G$ a7 M/ h/ I
  487.         unsigned char byte;& Y# @5 i) x" _/ M- k  F
  488.         CE_Low();                                /* enable device */  d5 g5 B6 K( A0 n# l- [2 t4 \
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */# b2 Q4 Z+ a0 B( p
  490.     Send_Byte(0x00);                /* send address */: `5 w. T- d9 I+ n( V" Y
  491.         Send_Byte(0x00);                /* send address */
    * L+ a- u# y! q, w8 h
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */+ f; W0 [, X$ w9 [) o3 B
  493.         byte = Get_Byte();                /* receive byte */
    0 T7 @" d, j4 R  T7 j
  494.         CE_High();                                /* disable device */
    8 `. ]( _0 |6 c- i, k0 I
  495.         return byte;
    $ y6 p$ l8 b. K# L. u% I
  496. }
    # o* W+ x& [$ E0 z

  497. + l9 D$ \& K6 n0 }
  498. /************************************************************************/) o+ t: O0 g/ h1 v6 w' `5 p
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */0 `4 [. c: E; _/ p1 f  ]: X# ]
  500. /*                                                                                                                                                */
    ! O  N9 N- z$ i9 s( v0 p8 Z0 g
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */4 ~2 e# A. ~$ Z2 k2 Z, c, j
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */- j8 K' h: l$ e( U+ `
  503. /* Please see the product datasheet for details.                                                  *// H! ~2 Y9 i& T* @% ~4 {8 O
  504. /*                                                                                                                                                */; w2 X1 Y& e$ {$ P9 D/ Y
  505. /* Input:                                                                                                                                */$ K7 m) _5 T$ Q3 h$ Y6 m/ h
  506. /*                None                                                                                                                        */
    6 ~( E5 L; B: W8 w2 `
  507. /*                                                                                                                                                */
    + w2 B* @9 r4 G) a$ I) Y2 I) Q
  508. /* Returns:                                                                                                                                */
    0 |- B# g4 y( l* @1 J: _7 m
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */- w6 {0 l/ \* F/ K/ \  w) F8 X
  510. /*                 and Device ID (8Eh)                                                                                        */! z- @5 X; Y: R
  511. /*                                                                                                                                                */9 ^. a" }5 S( k9 k3 a4 |
  512. /************************************************************************/
    ( Z2 s% D7 y; r& F2 I7 {* s
  513. unsigned long Jedec_ID_Read() , R; @: _0 N! y6 c7 {( ]$ M
  514. {
    & V+ q) ~/ [3 R8 U
  515.         unsigned long temp;
    7 s; O2 K* |8 B  }
  516.         6 |' L6 e) s% J) C8 a
  517.         temp = 0;
    7 ^8 s) _0 I) t! g& Q6 T5 o
  518. 7 Q& ?0 N; r5 ]- [  R( A& h7 O
  519.         CE_Low();                                        /* enable device */
    ) ?1 \1 F& T. f% {1 D9 S
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    ' f. E0 I- J. b
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    ( }5 @4 }1 [2 M) |' h1 z
  522.         temp = (temp | Get_Byte()) << 8;       
    6 e4 y% Z  z8 P$ g  ^& Z5 m# ~: _
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    : w# V: y3 v. E( \( ~
  524.         CE_High();                                                        /* disable device */6 m$ Y6 q- V3 O
  525. " G2 o( i$ _2 Q/ X
  526.         return temp;/ M) |* x  h, v
  527. }- ]" s0 Y3 k2 s4 M: Y1 t/ R# P  N# b
  528. ) U0 m7 p" \8 e' F2 r+ D
  529. /************************************************************************/
    " N3 f: H2 J# k4 m. K
  530. /* PROCEDURE:        Read                                                                                                        */' F8 i4 K, r" ~* W, z+ |1 y
  531. /*                                                                                                                                                */               
    ( Q$ _0 m: y) A6 t
  532. /* This procedure reads one address of the device.  It will return the         */
    1 f) m9 r3 p4 t& Y3 s2 g
  533. /* byte read in variable byte.                                                                                        */2 k6 Q6 W: b7 [+ W: D' }2 ]
  534. /*                                                                                                                                                */
    8 ~- Q1 p0 G  x8 A$ B; D
  535. /*                                                                                                                                                */
    , [2 e: |  i& z4 R  d4 J1 u  v
  536. /*                                                                                                                                                */
    . g  Q: k4 {9 G9 O% ]; b
  537. /* Input:                                                                                                                                */" q  a! q/ r7 d/ Q% M/ {+ x
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    % J- F: Y( ^% j3 a4 U" j3 |" N: F
  539. /*                                                                                                                                      */
    ( D" U5 ~) H0 A4 l/ Z8 ~6 \
  540. /*                                                                                                                                                */$ r8 }( \" T8 J
  541. /* Returns:                                                                                                                                */
    9 `8 d: A7 C  I4 b) O# F
  542. /*                byte                                                                                                                        */
    / |( g2 c3 q+ ~% o! `# a
  543. /*                                                                                                                                                */
    " l* S$ [# P5 |2 U
  544. /************************************************************************/# j  p' b4 @: N- f8 J
  545. unsigned char Read(unsigned long Dst) 2 A/ r. J/ O' v1 m4 R: c
  546. {( d# Z' w2 X2 I9 i. L; \
  547.         unsigned char byte = 0;        1 p' g) Z5 t; E/ o3 F

  548. 3 Y8 S1 R; Q( i: G# q, y
  549.         CE_Low();                                /* enable device */
    0 y" ^' ~) o0 S* u7 }3 [
  550.         Send_Byte(0x03);                 /* read command */1 ?/ z" Q1 z; R# t
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    $ j' Y3 i, n9 i
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    4 r' r4 i4 K/ e8 }$ y
  553.         Send_Byte(Dst & 0xFF);
    ' V% F$ e: v% o% o* l8 C+ \
  554.         byte = Get_Byte();
    . Y6 J7 n; i* Y# j9 ^" z
  555.         CE_High();                                /* disable device */: {- V2 G/ S) C9 G$ O3 z
  556.         return byte;                        /* return one byte read */
    ' O3 C4 R4 M9 v8 E+ O! g1 z
  557. }% ?6 B7 ?; r' ^! D
  558. 8 b" {& q* M* N3 W
  559. /************************************************************************// }- L; }# h% i" ]1 ~
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    , _4 T2 u* S& k+ N( M4 \& ^$ n) f
  561. /*                                                                                                                                                */               
    ; g; G  ]% u5 Y2 ^
  562. /* This procedure reads multiple addresses of the device and stores                */
    , D5 ~' R! Q3 V% c; e6 `
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/7 m$ w$ ^7 @) y& M8 U, Z5 C
  564. /*                                                                                                                                                */2 q5 P9 c9 ~6 x! @- n
  565. /* Input:                                                                                                                                */
    + M/ v% M3 m2 O
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : Q- n9 B5 K# X4 D9 ^5 C3 y% j' J" ^
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    ( I! a) o6 E# K% Z
  568. /*                                                                                                                                                */
    1 t' U9 w4 q- E. p! A
  569. /* Returns:                                                                                                                                */
    ! C' s9 l8 W4 ]# c) H& r) U
  570. /*                Nothing                                                                                                                        */9 d, E  Z/ S7 K* q& A1 ~- {
  571. /*                                                                                                                                                */
    % L$ C) A1 h% D( Z. G! X' N
  572. /************************************************************************/
    ! j( m7 L8 M; N" p/ A2 z9 w; e
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    / o0 P' d, h& A7 L5 J
  574. {3 o3 |9 s* N- t; N
  575.         unsigned long i = 0;5 Z: e# ?6 w5 e" l
  576.         CE_Low();                                        /* enable device */% p) D3 }' p% O% q
  577.         Send_Byte(0x03);                         /* read command */
    . z/ [3 c3 B/ Q. ]; R5 _
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */  t  [/ X. P: a
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));! P* f( ]& C, G; N. v
  580.         Send_Byte(Dst & 0xFF);$ }+ x4 i5 n- i7 r+ V4 }
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    0 c$ d5 F- a$ N, \! P
  582.         {8 [1 g9 G* h  d/ V7 r# g
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    / h5 Q. b# p) R$ m# t9 y- c
  584.         }* n  @3 A$ Z( `/ `* R2 i* e& m0 H
  585.         CE_High();                                        /* disable device */
    $ y  E7 Y( p* I

  586. 3 V7 d& F& l2 i1 \
  587. }3 V3 ?" R5 u- J

  588. 6 p; C8 M9 F! a
  589. /************************************************************************/3 [- w3 w; ~( ~# g* |. c
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    0 c; y4 H- b/ y7 ]! X1 y' C
  591. /*                                                                                                                                                */               
    / n2 {& P4 G/ u( u: k: V
  592. /* This procedure reads one address of the device.  It will return the         */
    $ I' |' R6 E+ p* b3 {
  593. /* byte read in variable byte.                                                                                        */8 K! Y6 L: R0 ]# O* o. H( ?+ E
  594. /*                                                                                                                                                */
    , x$ o" s( Z1 R1 V
  595. /*                                                                                                                                                */, X2 n# H6 S' \9 L$ C" C3 z  R
  596. /*                                                                                                                                                */% S3 N' c: x7 P5 q1 \. b
  597. /* Input:                                                                                                                                */! X- \- Z8 K! ]& g2 z) P( T
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */( u# h3 }8 d  @7 t8 C" b# B
  599. /*                                                                                                                                      */  T' |- S2 e! K2 A  M
  600. /*                                                                                                                                                */; ^+ f+ r  H6 U3 ~
  601. /* Returns:                                                                                                                                */
    ( S* f+ h6 i. @  F8 G% l
  602. /*                byte                                                                                                                        */
    ! ?3 h7 V6 j6 N4 c9 V
  603. /*                                                                                                                                                */% f& Z" X% a3 \& ~  t$ V
  604. /************************************************************************/& Z. e3 m% n" L( H3 e$ X4 h! I
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    9 F( ^9 m- G- F8 p+ J
  606. {
    $ s1 \$ {; w. |) i# Q' t" r. Z4 q# S
  607.         unsigned char byte = 0;       
    1 M+ R4 e: D+ b. W$ f
  608. % b+ g; F$ P* X5 B0 ]% f4 [( G8 J
  609.         CE_Low();                                /* enable device */$ D" X+ B" \% O0 C: B
  610.         Send_Byte(0x0B);                 /* read command */1 l# F6 A. c$ {1 D, u
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */- f  n6 B+ ?0 A, e0 j3 M
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));+ D, c. F7 j" G  s6 R  l. J
  613.         Send_Byte(Dst & 0xFF);( Q% t4 ^6 J9 U2 Y
  614.         Send_Byte(0xFF);                /*dummy byte*/! I% K! ~& K' ]" V& ]( a
  615.         byte = Get_Byte();: Q- r+ n  V  L6 z/ m) b- e+ J2 s
  616.         CE_High();                                /* disable device */2 t6 f5 n0 G" S, W7 G( y1 s! n
  617.         return byte;                        /* return one byte read */& g" x' s6 _: {8 G
  618. }1 e. F! v  n0 ^
  619. # [! \8 h, Y7 |5 p4 x5 ]% ]
  620. /************************************************************************/
    0 i+ @! a( `+ U& r
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */0 g7 k$ i6 j4 k# M2 R: r  [
  622. /*                                                                                                                                                */               
    ) i& `5 n+ [5 _. A; O& B  d- m
  623. /* This procedure reads multiple addresses of the device and stores                */
    0 X( C0 r7 y! i' ^) h: L8 E$ P+ O
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/+ V) j, e' y* i3 W% K9 w
  625. /*                                                                                                                                                */  Z: z! S6 l4 k7 @
  626. /* Input:                                                                                                                                */8 [2 G  U7 @  o+ a2 F  v4 `" E+ L
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */0 w7 d  W1 E/ T: u; l0 b
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    # h" y/ u) u% e5 c
  629. /*                                                                                                                                                */
    ( e' H4 L3 M' m/ P7 q1 \/ ]4 k
  630. /* Returns:                                                                                                                                */
    5 q+ b* G" t8 s* x
  631. /*                Nothing                                                                                                                        */
    , g) e- X% I" F( M* X( q
  632. /*                                                                                                                                                */3 b- i. ?' I2 w( X* Q8 ^
  633. /************************************************************************/, `  X' R2 ]9 D! F+ e5 z/ x: {
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)0 `( K: N, I  F, M, w" V
  635. {) |, F( K5 m, e% [& ]/ _0 }
  636.         unsigned long i = 0;- O* o# }& A) T+ {
  637.         CE_Low();                                        /* enable device */$ c! x; d/ ]' N! L0 O
  638.         Send_Byte(0x0B);                         /* read command */) F3 I  M3 A9 ^" x, l0 g  Q+ G
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    & |% @) h, q  @0 @0 Y! i
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));/ \0 H# T/ l8 n9 H0 X
  641.         Send_Byte(Dst & 0xFF);/ p. U& D' n# Y& J& H; {4 b! j* c
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    - ]6 m. p/ i* i8 j- E$ n1 v
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */$ D0 u6 _5 @& M, }) h
  644.         {
    . J4 l4 Z/ ^, L" m) ^
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
      V* I4 T. G  d
  646.         }
    % _1 r% w) Z7 k. F. k3 e
  647.         CE_High();                                /* disable device */
    # Q' R0 e) C0 G  x) R! G
  648. }6 l* D% H: N6 t" |) S( D) |

  649. 9 f% B: Q; Q) n2 B& M
  650. /************************************************************************/
    2 }$ F" y) |6 w7 s" H. _
  651. /* PROCEDURE:        Byte_Program                                                                                        */; j) c" {; K- S% b+ C* V+ y2 ~
  652. /*                                                                                                                                                */  J3 c! v( E( \' K
  653. /* This procedure programs one address of the device.                                        */1 [3 m0 D& V* }, z2 b
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    0 S; W% U% y7 c1 ]+ z! u" V  z
  655. /* block protected.                                                                                                                */
    7 ~6 |: C. n9 z8 O% d+ f2 A
  656. /*                                                                                                                                                */
    2 h# T' [% `0 Y" e4 R5 z; O
  657. /*                                                                                                                                                */
    4 t) A0 C5 |" s. k2 e
  658. /*                                                                                                                                                */
    3 ^. v- @0 \1 Q" U
  659. /* Input:                                                                                                                                */: Y$ ]/ @$ J( \, B0 m* I6 U6 e" E" n
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */0 s) g9 l& o3 I
  661. /*                byte:                byte to be programmed                                                                */
    ' q7 J* k7 s- ?4 U: p  q
  662. /*                                                                                                                                      */3 T  \$ K. K5 @5 K
  663. /*                                                                                                                                                */' `: ?. y: D, l- i# w( d
  664. /* Returns:                                                                                                                                */$ L" F$ R1 X* H1 x5 \
  665. /*                Nothing                                                                                                                        */
    ) e3 q% c7 }, ^' g
  666. /*                                                                                                                                                */0 |% H- Y$ q! N" Z
  667. /************************************************************************/
    * n0 {* A, X; }/ y) |
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    . C, ?% c; @9 @5 h6 g! P
  669. {7 ~- \# i$ ^5 N( Z0 A+ o/ m  f2 h0 @
  670.         CE_Low();                                        /* enable device */2 C+ Y, K6 r# }
  671.         Send_Byte(0x02);                         /* send Byte Program command */4 `$ h8 s# g* f: U+ T% A& P
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ! K" n% s  ^/ @9 s( v
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));* U" k. X8 ~& J' Z
  674.         Send_Byte(Dst & 0xFF);$ G- K8 r$ c; D2 R- v
  675.         Send_Byte(byte);                        /* send byte to be programmed */; V' o3 i  A5 Z( w4 W
  676.         CE_High();                                        /* disable device */1 x. U; _& o9 v
  677. }
    + l1 \3 O, o8 r+ D7 \$ {9 H
  678. $ s4 U; N: {3 A
  679. /************************************************************************/
    ; o& N% x6 \* M1 i
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */. Z/ P" V4 o! c- a
  681. /*                                                                                                                                                *// d) T, E" z* A" Y6 b8 j
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/2 b+ H9 q8 P  d8 w8 a' [
  683. /* the device:  1st data byte will be programmed into the initial                 */1 [, f& w6 v' D% u$ y) j/ C$ F6 @
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
      D8 }2 V' p* h" s& _0 ?0 b8 |- k
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    : S7 g# B& [) [
  686. /* is used to to start the AAI process.  It should be followed by                 */9 I. q9 V+ n6 A  t: J
  687. /* Auto_Add_IncB.                                                                                                                */
    6 U0 o; b' \( D- Y
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    . b4 I# I) Q0 N3 `( A' {9 z
  689. /*                                block protected.                                                                                */8 w+ C  @3 a7 I% h+ B$ ~! C! C
  690. /*                                                                                                                                                */
      E$ p8 P  M/ s- f) p5 ~( ?
  691. /*                                                                                                                                                */2 t$ D- t) |" R. S: f% r5 o
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */+ u6 i0 y. \* h/ E+ e
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */- }; d, g: u4 ~. {  I+ b( ?
  694. /*         unless AAI is programming the last address or last address of                */
    ( W, S8 R7 _: a5 @3 b
  695. /*          unprotected block, which automatically exits AAI mode.                                */& Z! @2 x& Y; N& b3 n
  696. /*                                                                                                                                                */1 m5 \0 M2 w( \% H
  697. /* Input:                                                                                                                                */
    / n1 s! w8 R$ s0 V2 ?5 g
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */4 n8 f/ J( C& H# k/ q8 ~. d5 I
  699. /*                byte1:                1st byte to be programmed                                                        */
    6 ?$ G$ _  e4 q
  700. /*      byte1:                2nd byte to be programmed                                                        */
    ) t8 H6 g' c8 |
  701. /*                                                                                                                                                */& r3 a3 I( N( c' J* G" m1 {6 Y* G
  702. /* Returns:                                                                                                                                */
    0 }9 J* @# X/ I. i$ a
  703. /*                Nothing                                                                                                                        */
    4 I& K  @5 v, |0 |, t* j3 L/ u( A6 f5 \
  704. /*                                                                                                                                                */) a" b/ d; G  d6 Y
  705. /************************************************************************/
    2 x2 o/ L$ o- E* f
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2). d; }3 y: H3 W+ [. p! K& `9 l; E
  707. {# u: U6 b0 `- U" f1 h" }7 \
  708.         CE_Low();                                        /* enable device */, R" ]9 N, ?% w% r7 g
  709.         Send_Byte(0xAD);                        /* send AAI command */
    0 m% G7 u. D" w  p4 {6 J5 i
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    2 R' E4 E% P/ @! P
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));) S  x4 R) G- u4 ~, q+ k
  712.         Send_Byte(Dst & 0xFF);
    3 q( e  O. E6 Z9 c
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    ! P, H& b3 D' |" b0 b  x; K
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */' M! s1 y5 K1 ]
  715.         CE_High();                                        /* disable device */8 O% W0 r6 \" G) U" W9 Q- m7 y
  716. }
    $ X6 t, {: a* y6 y9 N: B: u

  717.   t6 u. E! U. `
  718. /************************************************************************/
    * A; a" L5 G2 a- \' L
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    4 c( D* J* j  \
  720. /*                                                                                                                                                */- @5 I) l% k# n1 T
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    - j* U, k# h, w4 v+ y7 z. b
  722. /* the device:  1st data byte will be programmed into the initial                 */
    ) T! R: R3 r$ i) a$ t: o$ O
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    ; O; T8 i% r. ]  n9 Z) m' Q. l- N$ ]9 r* X
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */' A6 O, f3 S! Q
  725. /* is used after Auto_Address_IncA.                                                                                */
    ) m+ r1 W) u$ L% p# ~  s! u
  726. /* Assumption:  Address being programmed is already erased and is NOT        */5 k. i% _( x, ?/ P9 v- s# E* H
  727. /*                                block protected.                                                                                */
    1 f# i: y* D2 E" c' k: n
  728. /*                                                                                                                                                */2 A3 a( a4 U* p1 z) v9 `' ~) z0 U4 v
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    0 l) R9 N$ Y- g  j/ b4 h. w/ H8 J5 s
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */8 t+ K1 Q0 _: H& y2 [% n
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */6 v! r8 x$ d" p' q
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    " j9 \: B7 Q; l$ r3 g, @
  733. /*         last address of unprotected block, which automatically exits                 */
    ' @4 K  W; Q) w6 I- c& s: s# n1 |, b
  734. /*         AAI mode.                                                                                                                        */+ l! G4 t7 c" A: y. l
  735. /*                                                                                                                                                */( T" Z4 ]$ }8 B2 z$ _, B* q! j
  736. /* Input:                                                                                                                                */
    % f) K! D5 |" N
  737. /*                                                                                                                                                */
    + z; A6 f* O+ A/ ?  t/ ~, g) _5 O
  738. /*                byte1:                1st byte to be programmed                                                        */
    ! F- L( O$ n7 n& R. D# K
  739. /*                byte2:                2nd byte to be programmed                                                        */
      _5 n/ x/ }: O+ ^" Z' ~
  740. /*                                                                                                                                      */
    3 W. A# W$ Z1 q* a9 F/ ?9 T
  741. /*                                                                                                                                                */+ f3 y6 ?' S( L0 o2 N
  742. /* Returns:                                                                                                                                */5 u/ Q+ R2 F6 Y$ j" E* w3 a
  743. /*                Nothing                                                                                                                        */
    - T+ V8 J# b6 X1 j0 c. Z' w7 `3 I" S
  744. /*                                                                                                                                                */
    " J5 U& j5 C5 Y$ h1 y
  745. /************************************************************************/
    ! n7 R# U2 E! W4 g
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)( y/ C" U5 I$ ~" U8 y3 _
  747. {: S/ o, ^7 V; I* t
  748.         CE_Low();                                        /* enable device */- o/ ^. C6 V$ C
  749.         Send_Byte(0xAD);                        /* send AAI command */
    / Z! O0 H% ^9 |6 e& a* k2 X
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    ' u$ N) \& E8 I& V) [
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */; M* a5 \5 t$ j$ c; Z3 J
  752.         CE_High();                                        /* disable device */- [8 y6 z" {1 S( }" s4 u" T9 e
  753. }! i6 b$ V+ W8 Z' G3 |5 R

  754. ; b$ ^: H: z  Z3 D
  755. /************************************************************************/
    2 I# r: {' F6 {$ s6 o
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    4 x# T2 ~  S5 I( T2 h- }% S
  757. /*                                                                                                                                                */
    & L; G, ^  L8 _& t5 x5 Z4 t
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */. Y" A, z" ~/ x' w
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */( f1 s: `; \5 z; l6 F' }5 T/ m, M! E
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    ) W, `5 A# V5 n; h
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    % E7 W# w  s5 W& ]3 n
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */& R' U! g$ F# X" S0 }' \, t, y! p/ P
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */* w: r5 d+ ?7 G" J; J
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */7 [  D, O3 B- \4 w' w8 o5 B9 I- C
  765. /* Assumption:  Address being programmed is already erased and is NOT        */* W0 Q, M# i5 w$ u
  766. /*                                block protected.                                                                                */: H7 {& h( i# [  C" M( b5 s( l3 w
  767. /*                                                                                                                                                */
    $ `! L- s, _' r1 }4 n# H
  768. /*                                                                                                                                                */& f4 K/ U: _/ h3 J
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    * V5 z( W. M; a7 R9 y
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    ( M- n; O  Q; Z# q; G( o
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ' m# ?# @3 T3 l) S
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    $ J# K( a' O0 y
  773. /*         last address of unprotected block, which automatically exits                 */  [1 i; {3 `8 l
  774. /*         AAI mode.                                                                                                                        */
    % v+ Y! A6 j( v. a
  775. /*                                                                                                                                                */
    " \/ a# v$ Y8 p: V+ O4 G+ m/ D/ T
  776. /* Input:                                                                                                                                */2 m: d9 f7 y7 p5 f8 B
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */* v/ ?) U6 W$ g; q' Q! C
  778. /*                byte1:                1st byte to be programmed                                                        */
    + ^+ q  m" ^2 y2 Y0 q6 k
  779. /*      byte1:                2nd byte to be programmed                                                        */
    ( g9 \5 z  |* _+ m+ n+ q) ~: O
  780. /*                                                                                                                                                */
    1 W" Q% W0 ?# C! P
  781. /* Returns:                                                                                                                                */
    7 m$ M# S0 `7 y  M! v! y0 J( ^
  782. /*                Nothing                                                                                                                        */# O8 w' h, O' I" n/ ^0 r2 }
  783. /*                                                                                                                                                */- g% l- N! R8 s# a
  784. /************************************************************************/( @  O* X" p' q/ M! I
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)* T% E/ k! K: t, p/ r) d
  786. {' c5 M. U- _1 _, m& F% U
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        ; U5 E6 G& J$ {4 w6 b

  788. ' Q+ k# o6 t& Z+ G- v$ g0 A
  789.         CE_Low();                                        /* enable device */: J! e" g4 Q- a
  790.         Send_Byte(0xAD);                        /* send AAI command */5 |5 A3 w( H" H
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ( e  P6 ?( u  J! N1 N) z
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));! x$ f5 t: J% @2 z
  793.         Send_Byte(Dst & 0xFF);
      N4 u% ]% l% z
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    . @2 w3 }# k& y0 y
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    0 L9 A4 P3 q; ?5 f
  796.         CE_High();                                        /* disable device */5 ^$ Y$ L$ m) K7 C/ S. z9 P
  797.        
    / P$ g7 Z( q( X+ o
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    0 n( m9 r3 ?5 A$ C6 y
  799. 0 F4 d* \% O0 h$ o( ~2 f7 m% V
  800. }$ x( Y3 m" a1 K

  801. " ]0 o9 h, {. M  i- D" |9 q) y
  802. /************************************************************************/
    # a1 t  c: e% J! `4 v$ t- d
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */6 H$ c& U6 d( A" A% k* m
  804. /*                                                                                                                                                */
    & ~* l1 v" j& e$ u, n7 B5 ?% l! A
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */" P4 l, Y( A- J- ~, u8 C# C
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    1 Y! Y# d2 {$ z8 O6 h
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    * ^7 d7 B# b% H, c" r1 M
  808. /* the device.  The 1st data byte will be programmed into the initial   */3 d, d+ X# q9 A0 M
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */4 Q0 l; O5 M0 u- W9 L
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    0 V  e; m8 l4 {
  811. /* used after Auto_Address_IncA.                                                                                */1 n6 i) a9 f# ^4 C6 |. ~3 ~
  812. /* Assumption:  Address being programmed is already erased and is NOT        */0 h; n* T+ u" c+ t+ i1 n( ?8 ^
  813. /*                                block protected.                                                                                */" E7 {* ?( D  f9 C7 q
  814. /*                                                                                                                                                */
    7 o8 W8 f: z' l! [- i
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    3 `' @" o& P" h9 i' d. w1 w5 W
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    7 G  d; R4 n" C( f1 y) Z3 t# G) D7 K
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ! e. c, Y4 N8 N  \* L' V: h
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    ( A4 r* R8 |! k, ]/ P' p7 ?; N
  819. /*         last address of unprotected block, which automatically exits                 */
    6 {9 |8 t( {. O8 z
  820. /*         AAI mode.                                                                                                                        */
    4 y' T1 N+ S1 P% {# x
  821. /*                                                                                                                                                */' s) B2 s/ J# _0 ^$ ]$ k; f
  822. /* Input:                                                                                                                                */
    7 e0 J+ p2 H& x# x6 j
  823. /*                                                                                                                                                */. T8 @1 }3 e' f# J( N  g4 Z" O1 k
  824. /*                byte1:                1st byte to be programmed                                                        */: \1 N$ {6 \" U: [1 `7 K
  825. /*                byte2:                2nd byte to be programmed                                                        */
    % j1 _2 z% |) e7 @" ]% {" |$ X8 K
  826. /*                                                                                                                                      */  J* D. k! j% ~' B/ W' q3 q9 k" v  d
  827. /*                                                                                                                                                */
    * ~5 t2 X* n( k) Y& F
  828. /* Returns:                                                                                                                                */2 s' Q9 M1 m; n" c7 n
  829. /*                Nothing                                                                                                                        */1 C. d  o- ~2 v1 y" U0 \
  830. /*                                                                                                                                                */3 ]' g1 H7 u% D% ]" Q( L, a2 G/ a6 n
  831. /************************************************************************/# D- b+ T& O) Q% @3 x. g% X
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    ' U0 }4 j8 a$ [5 y+ L, G5 d
  833. {3 {. x$ z! O! j7 _& Y
  834.         CE_Low();                                /* enable device */
    + H5 j& v+ @( g$ ]2 n
  835.         Send_Byte(0xAD);                /* send AAI command */, D1 v6 B+ ?! `) A# g! v2 l8 y
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */1 l5 s; j7 @4 }
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */& Y. W  x6 Z0 ]2 x( m! g) ~% L
  838.         CE_High();                                /* disable device */
    4 K/ B# U6 l- B* y: s: Z

  839. ( Q8 q! s# ]1 i: r+ _( y. N
  840.         Poll_SO();                                /* polls RY/BY# using SO line */3 L" D1 I8 e1 @% |

  841. ! `' ]0 s+ m0 ^* b3 Q' r
  842.         WRDI();                                 /* Exit AAI before executing DBSY */; q/ ^2 x2 _9 d
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */! U- q4 ~8 q, w2 ?$ P
  844. }
    / H' E/ K) T  u7 j- t

  845. 8 \  ^0 O( c" r9 C, _% Q. U3 L, z/ e
  846. /************************************************************************/
    + a: U7 b  `5 U5 o0 m/ K: K
  847. /* PROCEDURE: Chip_Erase                                                                                                */% z7 G% o- t  `7 R
  848. /*                                                                                                                                                */
    0 O6 J. _4 a# R7 X6 Y' B
  849. /* This procedure erases the entire Chip.                                                                */
      m6 g9 b: s' `) G  ~; ~
  850. /*                                                                                                                                                */( Q4 `5 y1 r4 q/ N8 C
  851. /* Input:                                                                                                                                */0 w2 q9 W2 R* b1 H. l
  852. /*                None                                                                                                                        */
    " U. ]$ s8 `5 [* j4 H: U2 {
  853. /*                                                                                                                                                */% _: v3 {1 E- w
  854. /* Returns:                                                                                                                                */. X. w7 @; ^* }" Q
  855. /*                Nothing                                                                                                                        */
    6 D' Q& J3 t! w1 q0 b
  856. /************************************************************************/2 ?! }+ p# s& C5 U* W4 X: w' V
  857. void Chip_Erase()
    0 _( C1 O4 ?* X4 O( K/ h7 L
  858. {                                                1 T+ e- @) B. Y. F. v! y* F" i
  859.         CE_Low();                                /* enable device */
    % l5 h" h# e3 ?" N$ L& X
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    / U; l9 E) V' D7 `1 X' @# A
  861.         CE_High();                                /* disable device */
    4 H+ K; g  C. Z; w) |
  862. }
    3 D6 s. R# e- W2 B

  863. 6 T& o! z  u5 n8 U0 t- e
  864. /************************************************************************/
    % F$ `- Q& Z% r  \
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    # w& K7 @  \; Y$ o
  866. /*                                                                                                                                                */+ f" i) A! o1 o+ m0 W
  867. /* This procedure Sector Erases the Chip.                                                                */1 x' W  A3 V2 ?3 K
  868. /*                                                                                                                                                */4 @- a0 _/ f( @( E. h
  869. /* Input:                                                                                                                                */
    ! |; M; \6 N% F( K
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    7 B; @" }4 y9 @) i$ `
  871. /*                                                                                                                                                */
    5 V2 q& s4 y6 _! c6 J" X3 W
  872. /* Returns:                                                                                                                                */1 e+ K" Z, w& A
  873. /*                Nothing                                                                                                                        */
    * r1 m8 f5 X3 q5 x  s: E3 J% q
  874. /************************************************************************/
    + q& R; W4 [4 x# }
  875. void Sector_Erase(unsigned long Dst)
    ; j& d9 k* I3 z
  876. {; O7 I' B- f, v* U/ @

  877. 1 @$ s" O$ A0 d! B  w( X

  878. - j$ E" }9 @  W. _4 S$ T/ R3 F9 \
  879.         CE_Low();                                        /* enable device */
    ! d& L1 H2 @6 N/ W, }+ d5 d) {
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    " s  o' C2 K  J/ O! @
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */3 n& w" ^' T! i! ]  @2 c4 k
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ( b+ D5 o5 D3 R' U
  883.         Send_Byte(Dst & 0xFF);
    8 x; p6 h5 \, ^& N. k7 a: a! p+ f
  884.         CE_High();                                        /* disable device */* E& b0 t% @& l8 B& s
  885. }        - }* q1 W0 ~1 k% t

  886. - Q" h+ R5 [9 s  K! C: i/ Y8 H
  887. /************************************************************************/
    * Z$ F9 S3 R; B% D( i2 b8 s
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */( ~% r: v( l: V# j- b
  889. /*                                                                                                                                                */
    - S  i- {+ P4 K3 y6 E
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */: {8 L$ U" D2 L2 S
  891. /*                                                                                                                                                */
    1 ~% A: z& S! ]  k# u3 J# j
  892. /* Input:                                                                                                                                */" }2 Y! b7 h4 t4 B$ [) N' i
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */7 f5 E. @3 l- B) W1 d: `
  894. /*                                                                                                                                                */) p: o& V' E9 Y  Y) D4 \1 y3 v
  895. /* Returns:                                                                                                                                */
    4 x- V6 U( E5 O
  896. /*                Nothing                                                                                                                        */
    / i1 k. D5 h2 H( D. f6 p" q
  897. /************************************************************************/
    ' U( Q% }) Q; b( ]% P+ D0 m7 M
  898. void Block_Erase_32K(unsigned long Dst)
    $ E7 P5 k  Q/ S, \% V: g
  899. {8 {" f# g6 D+ ~) @% f2 L
  900.         CE_Low();                                        /* enable device */
    + j# q+ W# z8 k+ O! C
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    / {# y% I5 K2 W1 |& E% p3 q  F
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */9 L0 S5 D% [( L3 d2 J  T
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));3 A0 L$ i+ |2 E
  904.         Send_Byte(Dst & 0xFF);
    ; w: O! }& x5 T; l7 z9 Q; G9 d' z# V( }
  905.         CE_High();                                        /* disable device */* b; Z) G5 l; Z& T' j, b% c  t
  906. }7 U9 e# D: G$ F' Y, V

  907. * t# l2 L- R8 }) u( Z
  908. /************************************************************************/: d* g% }2 L5 i9 E. C
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    : O% ?0 `/ k8 ^9 s4 I/ D
  910. /*                                                                                                                                                */& \8 D) Z( t* u' C2 R* `
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    " ~  e4 g% L* ]  B: D8 h4 l) w
  912. /*                                                                                                                                                */
    , S# {7 z2 q! M' b
  913. /* Input:                                                                                                                                */- y! e4 W3 ]. _! r2 c' g9 Q
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + u8 r# R3 h1 ]+ V
  915. /*                                                                                                                                                */* _, P# v2 H6 \1 Q& R
  916. /* Returns:                                                                                                                                */& F$ k' q4 h% Y: t) j  s% A0 H: I
  917. /*                Nothing                                                                                                                        */
      ]: r1 b" D! `. h
  918. /************************************************************************/1 W1 P# J: f) A& {/ C3 ~* q- N
  919. void Block_Erase_64K(unsigned long Dst)/ B: u, }8 a4 k- S
  920. {
    , W6 f1 H2 w! y3 r/ ?
  921.         CE_Low();                                        /* enable device */* R* q* ^1 ?+ o- i: p
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */9 f: x" t* O6 r3 f4 X$ a3 `
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    , G3 I% x9 }* V: {
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 R9 `$ ?# R- ~. z2 i& @+ g7 U0 D
  925.         Send_Byte(Dst & 0xFF);
    ; X$ }# ~8 V  `5 q; `
  926.         CE_High();                                        /* disable device */# A, a8 j$ T6 V# x  \% y
  927. }
    " W1 U$ p# g! n6 y/ z1 _' p! R
  928. 8 l0 m3 C# W% }/ \
  929. /************************************************************************/
    - Q* G7 ~& w0 Y; P
  930. /* PROCEDURE: Wait_Busy                                                                                                        */+ ^# n/ \) V  ]4 k( q
  931. /*                                                                                                                                                */
    % r7 B. P4 E9 w8 g- ~1 n2 Q: e
  932. /* This procedure waits until device is no longer busy (can be used by        */
    * |: B; H7 Z3 y. W, g( C& D
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    1 O2 h5 m( H" `: }
  934. /*                                                                                                                                                */* z7 H4 @! T! }- S7 G
  935. /* Input:                                                                                                                                */; |% p" ?9 v0 @9 P2 {* A% V
  936. /*                None                                                                                                                        */& ]; x  P1 u0 @# u0 n
  937. /*                                                                                                                                                */
    - m- @; n( b* b- S
  938. /* Returns:                                                                                                                                */* ]. r9 T* f# ^$ Z5 {
  939. /*                Nothing                                                                                                                        */4 ^7 W/ w4 i0 o- ?! i
  940. /************************************************************************/
    8 E% @% x' j* z* z' z& |6 F' }
  941. void Wait_Busy()6 Z/ p2 J& C$ E$ E% f, G; _
  942. {' b3 E% ]5 R" a
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    3 N* u5 x8 Z: g$ m. p8 r$ O2 F
  944.                 Read_Status_Register();' {0 m) D* x! E
  945. }8 y* E* d' k- W4 E* _

  946. / |' h; K7 m" x  X0 y6 y' x
  947. /************************************************************************/& i# W3 w+ \! X
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */, V9 g9 g  Q$ F
  949. /*                                                                                                                                                */& n6 P0 y6 d, V# p
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    ! a3 H; l( ^* k& Q+ r/ R
  951. /*                                                                                                                                                */1 ?+ u3 O) }) k
  952. /* Input:                                                                                                                                */% S, }/ [  D3 F$ D- m9 T+ G( v4 Z9 B
  953. /*                None                                                                                                                        */
    1 J- h( ^1 G. P. k( h/ S; u: a
  954. /*                                                                                                                                                */
    4 r; Z4 r0 {- a% X9 |; X
  955. /* Returns:                                                                                                                                */
    - P2 o9 q4 C7 w% T" d( a9 w
  956. /*                Nothing                                                                                                                        */
    $ s4 t* t6 z. P% ^- R
  957. /************************************************************************/
    ( ], x7 @/ C& ]. W' M1 i
  958. void Wait_Busy_AAI()) J5 [6 r/ k9 i3 L/ G' f. P2 V
  959. {
    ' D0 A0 y5 A" ~
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    - a! t/ A( \' c4 W( v
  961.                 Read_Status_Register();
    2 `+ X- K3 s) k/ b2 Q
  962. }& w- w) z* Z4 A% i* h* O( d7 Z

  963. 6 W/ p6 |0 W8 S/ n7 T+ E' r
  964. /************************************************************************/6 H" [( _! Y% I; J3 @: v+ }
  965. /* PROCEDURE: WREN_Check                                                                                                */' n0 e: }4 T, J  b. ~" f7 U2 L
  966. /*                                                                                                                                                */
    4 _4 \( `$ u1 p. P8 h5 @& `
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    . h& O: e- Z: U0 d% }) L  m: T
  968. /*                                                                                                                                                */' G8 K2 s5 x4 c2 |  h. Q+ w
  969. /* Input:                                                                                                                                */
    / t! u4 ~- v# p
  970. /*                None                                                                                                                        */
    ( x% W0 B0 C2 G* B& I
  971. /*                                                                                                                                                */7 x3 j* g9 b- I# i. c4 ~
  972. /* Returns:                                                                                                                                */& ~0 |! A# c8 Q  a7 x' W
  973. /*                Nothing                                                                                                                        */
    / _: ~2 Q. P* B% J6 [
  974. /************************************************************************/  W) V/ M& H8 |0 \% E
  975. void WREN_Check()
    1 v4 j  E1 H5 F/ r: M0 a
  976. {+ i6 p. n2 h* M, d3 S% \* E
  977.         unsigned char byte;& Q. h8 [% b, f+ o2 m- p- C4 q! Q
  978.         byte = Read_Status_Register();        /* read the status register */
    3 `# T! u' @; ]) X
  979.         if (byte != 0x02)                /* verify that WEL bit is set */1 n. h0 O8 X& s: _
  980.         {, N* G2 f: z+ A% d( }0 `* U
  981.                 while(1)
    4 S! d$ E, C: G; z
  982.                         /* add source code or statements for this file */' s6 Q6 Q- l2 T6 s4 t3 Y! A! }2 F
  983.                         /* to compile                                  */
    2 E# c( F0 `: \9 D, Q( I+ X
  984.                         /* i.e. option: insert a display to view error on LED? */
    5 B- ~( R7 J/ Y4 h: H/ r$ y
  985.                  3 {3 L) o# Q: ]# M
  986.         }
    + V; C, ~8 u; |6 Q  s
  987. }
    0 D' d8 K  N6 v2 L$ e1 t/ J

  988. ' H/ e- k+ [# C
  989. /************************************************************************/3 j" W$ z8 D2 p  ?; B4 B' A
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    ( S8 v% s) X1 o9 o1 l1 p: ^1 P" E$ A) ^
  991. /*                                                                                                                                                */
    : ?! `/ F& A" N* ?7 n5 E
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */$ h( S. V! e0 W; I0 I! f8 v
  993. /*                                                                                                                                                */- ]" U. {0 @6 b0 ~5 f' E3 I. f
  994. /* Input:                                                                                                                                */5 J2 [, D* m. |! X, Z$ S
  995. /*                None                                                                                                                        */4 E: {! m' p" E6 ~. Q
  996. /*                                                                                                                                                */( c% x' I' v  V: y2 I
  997. /* Returns:                                                                                                                                */6 T4 b: W$ D0 _$ E$ {/ q5 h5 n
  998. /*                Nothing                                                                                                                        */
    ; @7 n2 O$ y  D7 p0 O$ |* ?) u
  999. /************************************************************************/+ F: E9 a% F3 D* f
  1000. void WREN_AAI_Check()
    8 G8 L* U1 c( [( J. b1 a6 G; I& e+ l
  1001. {' c/ m' G& f4 Q, S# W# a7 y5 s  n
  1002.         unsigned char byte;
    6 Q0 q* k, q8 c; R; e- ?
  1003.         byte = Read_Status_Register();        /* read the status register */5 r) K; r+ |6 T
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    0 O) N7 G, Z; T2 n9 ?
  1005.         {6 E* a8 z' a2 ~2 I8 Q
  1006.                 while(1)               
    2 I% C* g! x5 a) t% i5 I2 Q
  1007.                         /* add source code or statements for this file */
    2 k0 L, o: z; i9 V
  1008.                         /* to compile                                  */! C8 F/ a0 ~9 C6 ?8 @* Z
  1009.                         /* i.e. option: insert a display to view error on LED? */
    # v2 H8 i$ Z/ f7 J: f1 q. \! u

  1010. ; Y" a1 H. O0 X1 l  A
  1011.         }
    6 X3 Z& v7 P: i; y4 i8 d
  1012. }
    6 X% ^  O5 P% P; X

  1013. ' B5 x6 g3 E, [# d8 C5 Y
  1014. /************************************************************************/
    % c8 y' ^( ?1 s$ z2 }
  1015. /* PROCEDURE: Verify                                                                                                        */
    5 ~/ W/ a& k% f' h5 L( L  W% Z
  1016. /*                                                                                                                                                */
    ) Q* B$ z# s+ C9 |+ G6 ?# Y9 g
  1017. /* This procedure checks to see if the correct byte has be read.                */
    ) Q& A, B2 h4 z+ f8 K+ v/ y
  1018. /*                                                                                                                                                */# H- a* q6 S2 }( j
  1019. /* Input:                                                                                                                                */0 L& k- r* A8 O- P
  1020. /*                byte:                byte read                                                                                        */
    / Q1 v/ R9 D0 i0 U6 ^
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    ( }$ }4 }# S3 ^# o5 x
  1022. /*                                                                                                                                                */
    1 `" }; |1 q; M  O+ g/ h- l
  1023. /* Returns:                                                                                                                                */
    5 D2 _  L/ a+ W
  1024. /*                Nothing                                                                                                                        */
    2 D3 U8 v- t3 c5 @. }
  1025. /************************************************************************/
    , w* `0 x* x( m' A& }
  1026. void Verify(unsigned char byte, unsigned char cor_byte), f2 e7 i# S' A7 V. a
  1027. {
    * C. `4 T. U0 E+ F" d
  1028.         if (byte != cor_byte)
    7 P% H( j  j( o- K8 R4 J8 w* l; w
  1029.         {7 J' T" L  L' c+ F. q( a6 S2 M
  1030.                 while(1)
    6 E; _4 [1 @' W  X
  1031.                         /* add source code or statement for this file */- M5 r2 x+ n$ g. Z
  1032.                         /* to compile                                  */- B  P- s2 n+ k, H
  1033.                         /* i.e. option: insert a display to view error on LED? */$ H4 `3 f% f7 M" b' f
  1034.                 " y! e: X6 e: k* a8 _
  1035.         }
    ' c( t: Q# e" f3 V/ N
  1036. }
    ! d5 d9 F7 `  ]' R# ^6 {( ?1 j
  1037. 2 K6 z# a- S! d' ^1 W7 W; k5 W
  1038. % D+ ?$ `* F: ?; e7 Y
  1039. int main()
    + ]& _9 q: v* d5 x- H- Q
  1040. {5 f: W! d1 J7 Z$ Q
  1041. ' i& b% R% E8 M0 _, S
  1042. return 0;" R( G9 V" a1 \
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:& ~6 s1 h4 Q6 }9 m% P
   main()
! F' x6 A$ N* \   里面怎么是空的呢?  Q0 I/ H9 P+ {
   发一份给我吧4 i7 a$ G& M9 k* Y# x
mail:luyijun2005@hotmail.com
$ g% T) m$ Z2 M; n/ i0 C咯。。。。
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。
& @2 E+ s* z% i( G8 L. T7 y5 m
9 z: x8 r( F8 p0 d$ z[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
7 Y% F! \8 b) L" _EC的代码在哪跑,你看DS的说明,每个EC都不同的。
* G0 `4 H) x! v5 v& T. U. k+ b! sOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
3 M- G5 ?! B0 B上面几个问题是你没看任何东西而白问。
; s; ~+ |5 g+ p% J- p6 ]4 {# E: ?1 C
0 y) j7 C9 y4 \4 G至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。) I& U3 z' {: S3 M4 \7 y

) o8 M6 @5 E: F关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!5 ]( o' u9 }& u5 `  b3 Y3 c2 b
6 n* ]4 I9 _1 F* O1 {1 ~
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”2 F0 _$ V8 U. B2 n1 T+ W# h

! {7 p7 A6 q$ j$ V/ P关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...$ n+ ^- Z& r% [% {# j7 E

! ^* r* @2 h2 W8 g# ~不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样' s; q5 h  G2 K6 ~3 B$ X. g9 {; t
似乎要把SPI能support 到最大,这EC chip应该有好卖点
5 @( @: j5 F9 r5 f8 i% ]' k) mBIOS功能要不要强大,也就决定了SPI Flach的大小1 @+ A# R* q0 V) X/ T
我是这么想的~让OEM去决定要挂多大!4 q- R0 R4 _, w- o' r0 Q: p
如果我司有BIOS工程师就好了~哈
8 k" O* i) Y* ]" h8 _" yWPCE775应该算很新的东西,来看它支持到多大?
4 _0 h) b% I! R8 v7 I; l8 A
0 U1 a* f% x& M1 P0 l另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte0 `/ C  b2 M0 J  X3 U
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.' n* e" Q/ n. S" w# R8 E8 |- e
# L6 Q. s8 L7 O/ h3 O, A$ e# S
这份driver收下~希望以后有用到
0 t, C2 ?$ _+ Z, i" l* }6 H! K: h谢谢bini大大: N$ U9 h7 N# ?

0 E6 j7 z3 H; t3 E0 E2 O很新很新的新手,如有错误请指正 (准备看第二家的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(): H9 E' \5 E$ c( D* B5 G4 h( C
{. b) S/ a2 o. T3 i; U( {
        unsigned char temp = 0;
$ o0 n- s% k( X/ e        CE_Low();4 p! Z' V- A8 I5 Q
    while (temp == 0x00)        /* waste time until not busy */
# v, e# C$ j$ T" a                temp = SO;  c4 R( p( ^" ?1 f& Q1 B6 \( h
        CE_High();- \; j) `8 n7 M# ]9 B. o/ Y2 N
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)1 }( C6 }! O7 A: O  d# Y; C
{9 b; ]0 M" w# S2 M3 k
        ; V9 n3 K* C( M, V
        unsigned char i = 0;
; {9 {3 u- ?6 K        for (i = 0; i < 8; i++)- Y/ A- ]- g, d+ O+ ~0 ]
        {/ b1 M# {- R1 d8 Z& o+ Z
                * y, y  w. A2 g1 F
                if ((out & 0x80) == 0x80)        /* check if MSB is high */
% c/ r' o. N* O- Q3 r, g                        SI = 1;' m8 u2 w! U7 e/ P& e0 b1 |
                else+ H7 \  n5 o5 m5 C: p7 ?4 Q
                        SI = 0;                                /* if not, set to low */& v4 {, Q! @) }* E' u
问              SCK = 1;                                /* toggle clock high */
! d% ^0 @  Q4 A5 ^; j- c   题            out = (out << 1);                /* shift 1 place for next bit */# [4 u1 s) k$ D. e1 }( T
                SCK = 0;                                /* toggle clock low */
% \7 A, S' w# l) C( o        }
# b4 x" f% r; @}
6 `# u% ~3 a/ a$ J( X 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-7-21 02:18 , Processed in 0.098392 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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