找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54998|回复: 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
    , s' \3 U$ j" M/ C# {

  2. # _" j' [: s; ]
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory0 t6 E$ g8 F" R9 b

  4. : }! H5 K+ R$ m' P5 p5 g
  5. November 4th, 2005, Rev. 1.00 W8 W1 C2 L5 Y& @9 ]5 e4 t( [, ^
  6. & R! n% ~, v8 y+ B6 \5 o1 r( b+ ]5 A
  7. ABOUT THE SOFTWARE5 d/ J& i( d, i2 J9 `
  8. This application note provides software driver examples for SST25VF080B,
    $ V: S8 s: K' g8 H; l) L
  9. Serial Flash. Extensive comments are included in each routine to describe
    0 Q) n! R& ^0 t7 i' a5 [% X8 ]
  10. the function of each routine.  The interface coding uses polling method , U& s9 s' x" u$ ~3 R
  11. rather than the SPI protocol to interface with these serial devices.  The
    7 x! U8 ?; N, c9 }( E+ t! N2 v
  12. functions are differentiated below in terms of the communication protocols
    & x) x. t5 d  X) \
  13. (uses Mode 0) and specific device operation instructions. This code has been
    ; C0 ~; m+ @2 ~# ^$ b; i+ M
  14. designed to compile using the Keil compiler.
    * X' A& S% ^$ s9 U( M
  15. $ V6 N& K7 R; Q: n
  16. ( Z( x* J' c  z6 G" O0 T1 V) Q$ T
  17. ABOUT THE SST25VF080B
    5 ?8 W" _! [/ S1 b" b3 n
  18. * r: l! g, \/ T" {2 q
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    6 ?; U" o* r0 z; d
  20. conjunction with this application note for a complete understanding & K, ]0 \5 r) t
  21. of the device.
    3 K" W/ t5 _# [; t
  22. 0 I: Z. @: U8 K) s. ~6 Y; n$ c2 U

  23.   g/ T( Y5 O. y1 j
  24. Device Communication Protocol(pinout related) functions:
    * o- a: [4 _2 J% ^7 V

  25. 8 V# C9 |" O# ?
  26. Functions                                    Function
    : ~: s$ C  [  @
  27. ------------------------------------------------------------------/ N1 o! }& Q( p. r
  28. init                                        Initializes clock to set up mode 0.8 K2 u& U% b& Y# G
  29. Send_Byte                                Sends one byte using SI pin to send and
    8 N& v/ L3 A! b) t
  30.                                                 shift out 1-bit per clock rising edge
    0 n( k: \9 ^: t. N! |% V
  31. Get_Byte                                Receives one byte using SO pin to receive and shift # w% T" ^# B( I+ Z3 z) }& w
  32.                                                 in 1-bit per clock falling edge0 }1 n$ e7 z7 u
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming) |) A8 P. u, c# f7 S& X* [7 G9 L
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    1 ~- S, q: R+ l' Y; {; T
  35. CE_Low                                        Clears Chip Enable of the serial flash to low! O, @  x: N4 n% `
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    ; Y$ z5 S, R' X
  37. Unhold                                        Unholds the serial flash+ L6 b% k) A  T
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    6 o0 ]! F+ l# p4 P5 c  o5 K, ~- a
  39. UnWP                                        Disables write protection pin
    - f' g+ Y6 }0 h- R/ ~3 K+ H
  40. & B; a  L/ M8 u. f
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code7 \+ b3 V9 M( M, j8 L
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your5 }' {9 h9 ]/ l# T, w
  43. software which should reflect your hardware interfaced.          0 L) P2 ^% ?7 _7 f# x

  44. 6 a, k6 L( E- _  \0 |4 [/ \$ u
  45. / D& R6 }; D6 h) r
  46. Device Operation Instruction functions:: y. _' i* P; }& E8 F5 G+ N

  47. % x/ J- o8 |6 k4 e- ?7 N+ m& D5 o4 U
  48. Functions                                    Function
    + p! ^4 Q+ t7 |' k- V
  49. ------------------------------------------------------------------7 |- b$ c4 X8 ~& X0 c% u' @
  50. Read_Status_Register        Reads the status register of the serial flash
    ' M! _: G3 S4 L9 g0 H
  51. EWSR                                        Enables the Write Status Register) a& l+ [  y, s, j" t* `, F
  52. WRSR                                        Performs a write to the status register8 d( o* v" i2 y, z: k4 M6 r7 G
  53. WREN                                        Write enables the serial flash
    % p4 @' q& a; E3 i7 D6 [0 i4 L  z
  54. WRDI                                        Write disables the serial flash
    # P. n& w: C2 c6 a6 n! d$ D
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming5 f9 C4 j1 J4 K- p
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming" J; B3 J% o# `0 b
  57. Read_ID                                        Reads the manufacturer ID and device ID' ]1 s* w: x9 c9 C- y" x
  58. Jedec_ID_Read                        Reads the Jedec ID4 C% b( N4 L+ w9 J
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)3 j8 I& D4 C7 b$ {4 e! O" Z; P9 r/ e
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
      `4 V/ a3 t0 p6 ~, P4 G
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)3 m" U/ f3 E; g! a% d
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)+ L/ [% {1 l6 p
  63. Byte_Program                        Program one byte to the serial flash
    ' F% A) U  A/ |; |
  64. Auto_Add_IncA                        Initial Auto Address Increment process% g$ L' a8 o, f+ ]/ G7 _+ q% M
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation+ p% v  k6 X. ?* e# h- M4 S  ?
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY" B% s1 s- V" L, U* b
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY, ~' E1 o7 T$ o, C/ X$ `8 n
  68. Chip_Erase                                Erases entire serial flash
    9 r4 Z$ f" {+ _1 W$ i2 l
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash/ A+ c9 L5 w# M$ @2 ]% v! Q
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash9 Z# |- J6 y' z9 }+ d
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    8 t3 M, V* G1 k6 z& S1 r
  72. Wait_Busy                                Polls status register until busy bit is low1 m& M7 W4 l1 h+ X+ C' j9 t' P# G6 a, H
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming& A+ p. L. o- Q! ?; |$ Q) J
  74. WREN_Check                                Checks to see if WEL is set
    4 }! b: W- G9 K6 H* r; |) M( @
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    / Y2 o: _4 r. a( j$ F, V

  76. ) D3 A$ o7 S" }& k
  77. 5 ~& j7 j, b  J- Z0 i( q9 Y" q" ]
  78. + u, L& ~1 p9 Z9 X$ V" y# l
  79.                                                                      
    - E. F8 n/ s) x5 B
  80. "C" LANGUAGE DRIVERS / ?/ B. d6 m2 B1 H  D6 y
  81. 0 t* ^) Q9 i" Q" t0 D  w
  82. /********************************************************************/6 Q6 c6 J; k9 j1 Z
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */' o- B# \& O. V( a9 x/ L5 y# ?
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    . A& ^# i9 M) f; X
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */' Q) Y( E! ?% |. E# ^$ ]
  86. /*                                                                  */
    % d9 h& `: k: Y& w
  87. /* Revision 1.0, November 4th, 2005                                                                          */   8 \$ V" U- g0 Q5 Q$ B. e
  88. /*                                                                  */0 P- D4 X& \  y
  89. /*                                                                                                                                        */
    ' y; V$ s  |/ T! M1 Z- O. y, p
  90. /********************************************************************/# L" D  X& N& T3 K; z

  91. $ D1 l& Y  z: o3 v( k: O/ `$ [7 k$ J
  92. #include <stdio.h># I% b% Q6 R- b1 m3 G" V* c1 d; c
  93. #include <stdlib.h>& h4 f; V8 f$ D0 A! \
  94. - L! ~' K- m: |6 n4 E' t
  95. /* Function Prototypes */1 m3 i( z2 N" t. U0 F( S8 B

  96. " q$ s! I/ Z: w8 o6 }& f" Z
  97. void init();( n) Q* u9 t8 s' e4 z. J
  98. void Send_Byte(unsigned char out);. S9 }0 x, Z% |5 T
  99. unsigned char Get_Byte();. [7 d( @; N5 O, x8 ~7 B1 l7 A2 z
  100. void Poll_SO();" I. |! [' _# @, ^" {6 G
  101. void CE_High();
    8 B) C! Z8 c2 O2 X8 O
  102. void CE_Low();9 W7 m, N! O2 j: I
  103. void Hold_Low();
    2 ]  x& Y. R; D5 V; z. }/ U( o
  104. void Unhold();
    & a2 V# c) E, X0 t# p5 @
  105. void WP_Low();
    * U/ T& ~& S: F
  106. void UnWP();
    " P, I+ m. u8 p( \! K7 _
  107. unsigned char Read_Status_Register();* z: A- I: f: d; L
  108. void EWSR();
    & D" `3 T& q4 Q
  109. void WRSR(byte);! X/ L5 O* n2 S8 n0 j' J" K! h, a
  110. void WREN();
    5 u5 f5 Q" O' D; l
  111. void WRDI();2 A% d9 q, M# D1 m5 Z) t: ^6 g7 z
  112. void EBSY();
    4 o# t. r" Y: B1 K
  113. void DBSY();- D1 `9 r& e/ h" g- f" N
  114. unsigned char Read_ID(ID_addr);" w, r  ~0 W. W! {8 F7 j
  115. unsigned long Jedec_ID_Read(); 5 Q0 B+ ]( r6 g# y- i8 P- W
  116. unsigned char Read(unsigned long Dst);0 m: ], i4 H* z% J5 r5 E
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    , L9 [& z+ E: p, d, ?
  118. unsigned char HighSpeed_Read(unsigned long Dst); ( f  Q% X7 Z: x  [% P
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);1 `, L5 o" ?9 ?  R7 g/ o9 E: _; }
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    1 r9 s% ~' M& R, S) k7 t' `: K0 H
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    3 D. w; e0 u4 f4 Z
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    ) U, ]9 [0 \+ Q- o
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);) w% x  ?9 f/ ]. O
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);& d) t6 O7 W* A4 G5 w) D7 @) V1 r
  125. void Chip_Erase();
    % s: i9 R. r) j9 c4 x7 G
  126. void Sector_Erase(unsigned long Dst);) ^( d& o' f" b
  127. void Block_Erase_32K(unsigned long Dst);
    * l! d- R. V) u: a, q' t
  128. void Block_Erase_64K(unsigned long Dst);
    / k+ n* F! ^9 X. K' b5 e
  129. void Wait_Busy();' m9 {2 S$ P% _2 }( S$ j2 X* B" Z
  130. void Wait_Busy_AAI();
    9 q( L7 z6 B" O  j# K( l! l
  131. void WREN_Check();
    8 u  x4 f0 m7 s0 s
  132. void WREN_AAI_Check();
    7 L2 C* y% B7 e6 l# F
  133. 9 u. p+ p8 f4 s/ G( Y4 T
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    0 C+ b4 b) }. O0 N) c6 F

  135. % m$ S+ c7 c( w2 U% w) n
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    , Z1 r& T- O5 e6 [
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    * _; G1 h& g) H& t$ c3 v0 Y
  138. ! q7 a8 k: T( p) C6 B1 a8 Q+ V3 k0 M
  139. /************************************************************************// ]3 N6 _. U$ D' u+ x
  140. /* PROCEDURE: init                                                                                                                */
    # |) h$ H; p$ o5 v
  141. /*                                                                                                                                                *// ^* _& f* z$ F
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    1 ^4 I2 e  S# R/ y9 ^5 y) k! A3 E
  143. /* setting up mode 0.                                                                                                        */
    " G+ t( H* {% ~- T& `+ v* Q4 x
  144. /*                                                                                                                                                */" H$ R0 n. X+ ]( N' u& \" m" L# `
  145. /* Input:                                                                                                                                */1 ^6 ~: P5 D8 ~! `! q
  146. /*                None                                                                                                                        */: M# F5 ^' I; P% G! N% m
  147. /*                                                                                                                                                */* x4 o9 B0 Z3 x5 V, K5 r' B
  148. /* Output:                                                                                                                                */4 a8 ?: L- r" @# e8 z" X
  149. /*                SCK                                                                                                                                */
    / j' w3 F8 L7 p
  150. /************************************************************************/
    ( e. Q! P$ Z) U
  151. void init()
    4 e# R5 J2 l( f* Y# C; V$ l; t% X
  152. {( D; G/ l0 e  t. }( S$ Y# h6 \# Z; Y
  153.         SCK = 0;        /* set clock to low initial state */3 A* ]2 X2 _: k# k9 J& r
  154. }: m& u" q) @. V6 ~8 \: n

  155. / M9 w, t8 ?  y1 {  e: E; W4 u# _
  156. /************************************************************************/
    7 z% O- n$ L1 ?$ L! l1 ?" \
  157. /* PROCEDURE: Send_Byte                                                                                                        */! @$ I0 }5 R! m# _4 T
  158. /*                                                                                                                                                */
    # M$ A6 I. y( [1 R: K
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */( d' h+ P$ [3 H: q" J: `
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    : f/ B5 b, H3 ?, b7 Z( F4 N
  161. /*                                                                                                                                                */
    ) j/ \. }! V, v4 p6 @/ B
  162. /* Input:                                                                                                                                */
    , [- G, _' t$ i; Q+ b7 `" f. \  u
  163. /*                out                                                                                                                                */
    * a$ a; d2 V6 d/ h
  164. /*                                                                                                                                                */: I& ~0 \# i# X1 {+ d
  165. /* Output:                                                                                                                                */" X+ d8 ?. b2 K; b. T2 k* \
  166. /*                SI                                                                                                                                */$ R: f3 G  p# L! @( K
  167. /************************************************************************/. e. L% v4 y; J. b5 L5 t4 u1 U
  168. void Send_Byte(unsigned char out)& C9 I, n2 v0 ~4 Q8 t
  169. {! K8 b" @+ h/ P8 w  l) ?" L
  170.        
    5 C$ i! N6 O; W( [
  171.         unsigned char i = 0;. M" d7 a- J4 ?7 w1 J% O- H  t6 E$ q
  172.         for (i = 0; i < 8; i++)
    ! Q; I% X1 ?4 I! m0 W
  173.         {6 }8 o. |: d3 F4 X* |7 ~
  174.                
    6 f+ w& I1 |. G# Y. ~
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    ) Z- t1 s0 g7 g. e. T8 A$ Y
  176.                         SI = 1;
    # t! D  k: j& ^0 z
  177.                 else9 t" D. T4 X( Y
  178.                         SI = 0;                                /* if not, set to low */
    7 j& Z8 b. k8 y1 y; l; P1 W+ @
  179.                 SCK = 1;                                /* toggle clock high */) M+ s' f  r& T4 ]2 d
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    3 O3 M) f5 T, ^7 k5 M' U% S
  181.                 SCK = 0;                                /* toggle clock low */
    9 X& e: U. z# T2 Y0 w9 K. B
  182.         }
    + O% c. ^) i: F" m) p
  183. }
    1 `; v' g4 T5 p9 X1 s
  184. 9 ?4 k8 K) U  p: c( m' p/ y! i
  185. /************************************************************************/
    9 Z2 A; ?) {& x5 u. V
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    , ^$ v+ b* ?; s; Z- Y8 B4 g3 f
  187. /*                                                                                                                                                */! l- A! E; s2 o7 K
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    ; U# V# T' v1 t$ |
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    7 A1 e/ _( R* E' \" ?; K
  190. /*                                                                                                                                                */4 K  ^, }* K; s
  191. /* Input:                                                                                                                                */. \3 F9 o5 k& m/ o) f$ L; T
  192. /*                SO                                                                                                                                */
    4 e3 t( g9 J+ _5 R+ y
  193. /*                                                                                                                                                */
    0 G2 ?+ n8 _. p- e  p  W- m( C
  194. /* Output:                                                                                                                                */! }6 i- ^; W0 X7 J+ d
  195. /*                None                                                                                                                        */
    . ~/ T7 S% L  e! Z, F: b
  196. /************************************************************************/
    6 G6 }1 ~1 |) \& B6 k
  197. unsigned char Get_Byte()
    ! o1 Y# u* [$ p) R
  198. {
    $ E* Q, q8 q) O; T9 F, D7 J4 o+ y# N
  199.         unsigned char i = 0, in = 0, temp = 0;
    5 A4 i  p, _) t" Y& \. J5 F
  200.         for (i = 0; i < 8; i++)
    % p2 `; V  _8 }6 L+ H+ q
  201.         {8 t4 C* V9 c8 i; n4 o, q/ d
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    ! s* {" k2 ?, j3 @
  203.                 temp = SO;                        /* save input */
    ' Q( f! V8 x0 \& U% U& I
  204.                 SCK = 1;                        /* toggle clock high */
      Z3 I' o( b! p
  205.                 if (temp == 1)                        /* check to see if bit is high */. U4 v4 H$ M" H& [9 P+ [) r
  206.                         in = in | 0x01;                /* if high, make bit high */
    + q$ h  O: ]1 F1 }. [/ z
  207. ' P" Q$ \' N- y6 i# h
  208.                 SCK = 0;                        /* toggle clock low */
    4 x# b5 E  C0 x4 Q# j+ T

  209. " h' u5 W# ~5 B! i1 L
  210.         }
    4 V7 E1 B% b4 |- }5 b1 X* s
  211.         return in;
    8 r$ n' W' R! j2 ?+ e5 p$ `$ \9 h- q
  212. }% ]% A. L7 F; E* ?

  213. 4 |9 \( z1 L+ s* p) G) O
  214. /************************************************************************/$ q; m5 V. j8 Y( o
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    * i) [+ n7 O. V4 }" H6 d# j/ R
  216. /*                                                                                                                                                */
    7 a7 D' k5 B6 ~
  217. /* This procedure polls for the SO line during AAI programming                  */0 w* L0 I5 @+ c- U$ R
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    , i, c$ M2 U0 T$ ?& Q  W
  219. /* is completed                                                                                                                        */
    . G+ [) ~: C. @
  220. /*                                                                                                                                                */
    ' S  l7 X; g; I
  221. /* Input:                                                                                                                                */& t  _8 Q. |9 G4 c' q7 X6 P
  222. /*                SO                                                                                                                                */3 P) Z2 }' m3 S% |( q/ C
  223. /*                                                                                                                                                */
    9 W, g1 h  X. G1 ?/ J
  224. /* Output:                                                                                                                                */
    1 e) e) D8 n5 d6 Q6 U
  225. /*                None                                                                                                                        *// Q" P9 `0 t/ W+ F; w4 G
  226. /************************************************************************/3 k* E5 ]# Z3 c0 S* [+ D  ]
  227. void Poll_SO()0 u- U. u! K7 K! q  O1 s" R2 t/ V
  228. {: T% ]2 g6 |" [% X& d' a. E& x
  229.         unsigned char temp = 0;6 E$ }" p( o, p
  230.         CE_Low();: f' ~$ v0 t, o2 R" n8 C, }% X% d
  231.     while (temp == 0x00)        /* waste time until not busy */
    7 s" A5 w0 v8 @4 a2 q) ~" x
  232.                 temp = SO;9 o+ r3 d3 f3 @6 Z$ d
  233.         CE_High();5 h# e" X1 m! T, G# D
  234. }
    * w$ [# l5 c5 B2 H& g9 J; `
  235. " j& Z2 H2 F- t5 e9 ?# U4 V7 \6 t# P
  236. /************************************************************************/
    5 y# E( |, j, \/ x9 e/ j
  237. /* PROCEDURE: CE_High                                                                                                        */( S. o: u: B. Z5 b3 L# o
  238. /*                                                                                                                                                */6 T9 E" _6 b4 m  [
  239. /* This procedure set CE = High.                                                                                */
    2 a8 Y+ L% ]# t$ F
  240. /*                                                                                                                                                */
    2 h* u4 E: C. Q1 p2 w
  241. /* Input:                                                                                                                                */
    ( O0 R$ q8 W% r, D" C
  242. /*                None                                                                                                                        */
    + i* ~8 x- ]6 n8 V( ^4 K
  243. /*                                                                                                                                                */
    $ d  p7 @& `4 v7 s
  244. /* Output:                                                                                                                                *// s3 ^' w1 I/ j" n! Y, y) ?+ I( n6 E
  245. /*                CE                                                                                                                                */% l6 h+ k" f, H$ r
  246. /*                                                                                                                                                */8 W; j& P' `" d1 t# j, \' N
  247. /************************************************************************/
    : K' w$ J, X% U4 _# C8 S
  248. void CE_High()
    % }. H- [* W- Y! k* _: b: a
  249. {
    $ i. P9 h3 C$ w; }: n3 S% f- {1 ?
  250.         CE = 1;                                /* set CE high */
    % x- E- E' D9 @  j4 K6 i
  251. }, n5 Z9 }- `% I# |) R
  252. . E7 n6 {6 H7 [8 y  j& ?
  253. /************************************************************************/! s8 `, O& h% `8 ~6 C
  254. /* PROCEDURE: CE_Low                                                                                                        */& b3 [: ^5 K2 p6 h' D) `
  255. /*                                                                                                                                                */
    : p5 O8 z; E1 X9 h! w2 X6 x  L
  256. /* This procedure drives the CE of the device to low.                                          */
    + p7 B) }- }* `8 j
  257. /*                                                                                                                                                */0 E2 N# U# K& N) K8 f/ P
  258. /* Input:                                                                                                                                */3 ?' \9 ~; Z$ n) S9 I& F
  259. /*                None                                                                                                                        */
    0 R6 G) u/ k4 Z; F
  260. /*                                                                                                                                                */
    ) n/ y6 G9 Y7 j' d8 ~
  261. /* Output:                                                                                                                                */
    # d& |' n$ H: W# z3 p9 M9 c
  262. /*                CE                                                                                                                                */
    ) u- k+ _9 `1 c8 s3 N& _
  263. /*                                                                                                                                                */- r0 t% v4 N# f2 p2 [* \9 o" s/ M" {
  264. /************************************************************************/8 b/ [+ T  s4 G0 [0 X9 j5 B' u  ]$ G
  265. void CE_Low()
    " _" @" E" Z" t' e. r
  266. {        ' T4 t( A/ Q6 u: p- F$ x- O6 A
  267.         CE = 0;                                /* clear CE low */
    ) Q1 g; f7 W8 V3 Z4 a) @
  268. }; w- p- n, ?+ h% [- S/ ~

  269. 8 p$ `# L: ]9 W
  270. /************************************************************************/$ ]/ T) o1 A0 L
  271. /* PROCEDURE: Hold()                                                                                                        */
    2 q% C, u. d8 v: i
  272. /*                                                                                                                                                */
    ; U. i' ]* V: v# }& R9 A7 J* b
  273. /* This procedure clears the Hold pin to low.                                                        */8 F$ ]" F: c6 m2 E
  274. /*                                                                                                                                                */9 h0 b0 ?1 R5 p* S* c
  275. /* Input:                                                                                                                                */" U& v1 S1 ?) z! ]8 j% g0 e
  276. /*                None                                                                                                                        */5 Y* U5 }: l9 k4 Z5 \
  277. /*                                                                                                                                                */% L, o; n& s0 x! I- k, B
  278. /* Output:                                                                                                                                */3 `# F' ~1 X& y) F2 S* I8 Z
  279. /*                Hold                                                                                                                        */
    2 r% E# y, ]+ H
  280. /************************************************************************/
    2 i) z9 y# u, }' i2 v
  281. void Hold_Low()* ]5 T& @7 H2 j6 f7 q, Z' F. a' z
  282. {6 K/ z9 {% `2 F3 O6 u
  283.         Hold = 0;                        /* clear Hold pin */: h" c6 L9 H  l5 J8 k& a
  284. }9 t. n1 }, \9 b* c( j( |4 J

  285. 5 l0 A" i2 @, [* s
  286. /************************************************************************/) m0 @. O; Y. p8 A3 z
  287. /* PROCEDURE: Unhold()                                                                                                        */5 N. B' `) s" }' N, W
  288. /*                                                                                                                                                */4 m) u( `6 V% I: f
  289. /* This procedure sets the Hold pin to high.                                                        */
    & F7 K3 }3 E5 \6 e( U6 t2 n
  290. /*                                                                                                                                                */- A' N" D1 o' J) V4 L' C; N
  291. /* Input:                                                                                                                                */
    , I( C/ X$ i' s/ N& G, V& F, l& h
  292. /*                None                                                                                                                        */
    2 I) A. g3 C9 P9 g1 y
  293. /*                                                                                                                                                */. D% K- f* B, j$ i: ]  U/ n% R
  294. /* Output:                                                                                                                                */
    0 c/ n" y5 H' U0 T) \& @  K) d
  295. /*                Hold                                                                                                                        */
      ~0 a* y* W0 x8 U
  296. /************************************************************************/: I$ L! g. ]/ W7 D8 I
  297. void Unhold()+ H* c/ }9 B  {( o
  298. {; l- Q3 w0 Q0 P2 N0 ]! @+ @% M
  299.         Hold = 1;                        /* set Hold pin */
    4 p* {8 ]/ h2 U2 s; p2 M0 j
  300. }
    / E# K# ]4 Z! c% f

  301. % D0 G$ i; N; q; O) c  a7 Z4 E0 l
  302. /************************************************************************/
    ! S, Y" {5 t4 |" u4 D- k5 q
  303. /* PROCEDURE: WP()                                                                                                                */
    8 |( V8 H8 C- k# c  {! a/ V9 ?
  304. /*                                                                                                                                                */" h7 d) U# i" I
  305. /* This procedure clears the WP pin to low.                                                                */
    - M/ r. H/ s- e( N" z) W
  306. /*                                                                                                                                                */
    $ G' C/ y8 x+ A; Y# U( j2 ^
  307. /* Input:                                                                                                                                */% {4 r% [/ n  w( ^; M) N& ^2 w
  308. /*                None                                                                                                                        */
    $ u! o6 ^# z. p; I9 q& z# e
  309. /*                                                                                                                                                */
    9 H( {( N# x9 @, L; t
  310. /* Output:                                                                                                                                */0 j/ U) {& d5 A% z; r& L7 a
  311. /*                WP                                                                                                                                */2 s& T+ ~5 Q/ a& \  E
  312. /************************************************************************/
    % ^0 _8 G2 V; Q. U: ?( |2 e
  313. void WP_Low()" @: y5 Z/ l$ ~8 N; ~
  314. {' a) ~- }5 N4 y4 D+ n
  315.         WP = 0;                                /* clear WP pin */4 m5 `# W3 {8 I6 \" g! q2 G
  316. }
    0 l- r& T' m& R' e  C

  317. ' u1 B' M% N& T2 Y5 l' F. q- o
  318. /************************************************************************/
    ' I, E) M" ]5 P) t% F) j
  319. /* PROCEDURE: UnWP()                                                                                                        */
    0 D' Y7 V. {7 U: t) {9 x
  320. /*                                                                                                                                                */
    0 J2 A; K! L$ {# Z2 g" V% y. _
  321. /* This procedure sets the WP pin to high.                                                                */
    * a1 ]. r8 R9 U* H- J% k! ^
  322. /*                                                                                                                                                */4 \; V6 P  o0 @. L9 k3 H
  323. /* Input:                                                                                                                                */* o% o: B! |; `: h/ |1 G9 R; h
  324. /*                None                                                                                                                        */
    * w5 X! N# }/ g6 Y& m& V, C
  325. /*                                                                                                                                                */
    2 {8 L8 P, ]+ R+ k. r
  326. /* Output:                                                                                                                                */
    % E4 ~& q$ W* q; e
  327. /*                WP                                                                                                                                */+ `9 z; k$ w+ s5 r4 u4 R; m- ]
  328. /************************************************************************/
    ) \8 ^6 \" }" v; z/ N- O
  329. void UnWP()1 M5 v, V8 ]* K6 {
  330. {
    2 B/ [) r6 B& m% G/ q( r- R& @
  331.         WP = 1;                                /* set WP pin */
    / d: H. g' M8 `, h1 l% \% N- E
  332. }
    ) a* e  n: j, f* J* U! p. n

  333.   ]+ ~9 O- _+ @' K( g( M; ^
  334. /************************************************************************/- N2 C- N0 a# v( L
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    , ]0 B7 G' A" @6 ?$ v
  336. /*                                                                                                                                                */# o$ [! k3 s. i7 x/ _
  337. /* This procedure read the status register and returns the byte.                */- M5 K9 k6 B, z6 Q4 f
  338. /*                                                                                                                                                */; y" E$ c4 ]1 t8 D8 q( @; }, _* U1 t  B
  339. /* Input:                                                                                                                                */
    ' ~0 ^7 d" `) S  L5 N
  340. /*                None                                                                                                                        */* X' [( ~2 b1 S4 c" E7 ^( ]8 b4 j
  341. /*                                                                                                                                                */2 G2 U5 O6 I% e8 j9 g+ J
  342. /* Returns:                                                                                                                                */
    / Z+ J. N5 ^; C: y  {4 Q- X
  343. /*                byte                                                                                                                        */
    8 m3 _9 z$ R; o
  344. /************************************************************************/) R, D$ z1 }2 w# n4 E. V
  345. unsigned char Read_Status_Register()
    ' G7 G9 f6 R8 y+ g+ d
  346. {3 f: m: G, s' `6 X9 x
  347.         unsigned char byte = 0;: R- C! Q) }9 z" k
  348.         CE_Low();                                /* enable device */
    $ q% d, |& X, I' Q
  349.         Send_Byte(0x05);                /* send RDSR command */
    * Q4 r- |5 [/ [& B
  350.         byte = Get_Byte();                /* receive byte */- w' p* S! S+ a" h2 ~7 b. O
  351.         CE_High();                                /* disable device */
    6 K5 ~2 ~3 @! q! o
  352.         return byte;
    - H  H1 V6 J7 m; b
  353. }# g+ W  i2 ?( S. r
  354. 8 \/ R8 S& L, S" z4 I2 {9 k9 `
  355. /************************************************************************/2 W) ?5 w! f; V7 z; m$ J  r  H' Y; z
  356. /* PROCEDURE: EWSR                                                                                                                */
    ' }7 D0 s; |7 W% }+ E0 d+ n3 }
  357. /*                                                                                                                                                */
    3 Z. R2 @) P/ t
  358. /* This procedure Enables Write Status Register.                                                  */3 `/ m& B: T8 j( x: |" e! E/ B
  359. /*                                                                                                                                                */$ j9 V/ r: \: B5 s" O- Z+ g
  360. /* Input:                                                                                                                                */$ I0 A3 g& W9 Z+ t3 \
  361. /*                None                                                                                                                        */
    ' L, u+ I( O: G
  362. /*                                                                                                                                                */
    ' \: \: F! K# S1 E" g
  363. /* Returns:                                                                                                                                */
    % {% @6 V& c% r; k0 G* A9 f, \( F
  364. /*                Nothing                                                                                                                        */
    2 E' z  \! F& Z/ P
  365. /************************************************************************/
    : J) @+ _! D  p' ^/ w$ G# W# b' T" b: U
  366. void EWSR()) {" l; R) j' {$ P: Q
  367. {0 M/ ^' H( V0 ]" T+ F5 g* v& Z
  368.         CE_Low();                                /* enable device */
    6 h1 t  {- s& q" M: F
  369.         Send_Byte(0x50);                /* enable writing to the status register *// i/ ^( D" ^" |7 z9 R
  370.         CE_High();                                /* disable device */# X5 q5 h( C% K" S
  371. }
    " L& I) @# R# a, W
  372. ' ^: @: ?$ U$ ?% Q/ }. I- c! _2 V
  373. /************************************************************************/) n, Y. }! t* D. I# h. K4 q" P9 I' X9 ]
  374. /* PROCEDURE: WRSR                                                                                                                */3 S4 N; P7 _* W; I& h
  375. /*                                                                                                                                                */+ x6 |! k+ [' N" C7 V# f2 j
  376. /* This procedure writes a byte to the Status Register.                                        */
    . N* ~4 a6 U8 g
  377. /*                                                                                                                                                */; Y, x( k2 U( C* W: K" [/ A
  378. /* Input:                                                                                                                                */( P+ V; M' ^: J1 b5 B" \
  379. /*                byte                                                                                                                        */. x# V8 s& D, d! J( \) j# x1 S# f
  380. /*                                                                                                                                                */
    4 i! j4 X& t  [. ]
  381. /* Returns:                                                                                                                                */! E5 {8 K6 r5 e
  382. /*                Nothing                                                                                                                        *// \/ N- B( @, ?' x0 r  I6 d0 a
  383. /************************************************************************/
    " J- C6 C* o, l+ @" Z+ u; \
  384. void WRSR(byte)
    6 @3 I, D; }. }/ d9 s
  385. {! _% J0 }6 Y+ ^* Z% a: `) [
  386.         CE_Low();                                /* enable device */" B, Y$ M+ W2 J9 d1 H- l# o! O! j; j
  387.         Send_Byte(0x01);                /* select write to status register */
    ! Q, _. V( R6 W
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    " y. r  Z! g2 t1 R0 u" S
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    8 H$ {9 B6 z1 x0 ~
  390.         CE_High();                                /* disable the device */! \3 d! x4 C5 {9 x& S) `. S
  391. }* m1 X8 g. h7 i, p; r

  392. 5 R: n/ Q5 z' ?! m
  393. /************************************************************************/; O5 ~, ?6 O, c1 p8 l. [! h$ z
  394. /* PROCEDURE: WREN                                                                                                                */& j' Y4 N9 L0 u$ u' S- h9 q# O
  395. /*                                                                                                                                                */) B0 V) o8 Z$ Z. B+ Q4 R2 [' V
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */2 o* ~: E, p$ Y% \; f; t1 U
  397. /* to Enables Write Status Register.                                                                        */0 _4 Y8 r$ f! |3 T. F9 O
  398. /*                                                                                                                                                */
    , Z* d( o# @0 P. X' V
  399. /* Input:                                                                                                                                */& V' X& Y& Q7 [. l
  400. /*                None                                                                                                                        */8 w( C9 g/ r0 S8 Q( ?: s) i
  401. /*                                                                                                                                                */% C5 n) S& ]- V% J1 a
  402. /* Returns:                                                                                                                                */9 o) f6 H4 M3 f' k
  403. /*                Nothing                                                                                                                        */
    2 \/ c/ l' x" h
  404. /************************************************************************/* {" ]* Y' `# c. i
  405. void WREN()+ Q6 H% S6 x  M, \4 A% R
  406. {
    6 Y! V( m8 C% |6 C. i* K  W# [
  407.         CE_Low();                                /* enable device */
    % Q% L+ I. v4 z  A* f5 p
  408.         Send_Byte(0x06);                /* send WREN command */
    # E- l: S/ Z# u/ l
  409.         CE_High();                                /* disable device */
    - K1 o0 W2 \# }2 ^# C
  410. }
    " Q# T" w8 {/ J+ T7 D

  411. ) h# X0 b! ?. U0 x6 A
  412. /************************************************************************// q# `  x) w/ c
  413. /* PROCEDURE: WRDI                                                                                                                */
    8 y$ u; {% W) J: h9 K7 A. O
  414. /*                                                                                                                                                */" Q( a( t2 N4 \8 C" e3 i
  415. /* This procedure disables the Write Enable Latch.                                                */
    ' I2 a+ f6 J) J" D5 m
  416. /*                                                                                                                                                */+ K& r8 @9 ?  i, |
  417. /* Input:                                                                                                                                */
    . p% n# \* s% P8 t3 i
  418. /*                None                                                                                                                        *// d0 s' F, M: o" ^
  419. /*                                                                                                                                                */
    , H5 j/ [+ e( a: L7 }' k  a
  420. /* Returns:                                                                                                                                */
    ) e2 ]2 R; b5 y
  421. /*                Nothing                                                                                                                        */
    - m9 _+ x3 b. e# [
  422. /************************************************************************/
    . w$ \3 C6 S8 E
  423. void WRDI()
    2 ~1 K. i$ g  S: ~
  424. {; W/ j7 n. e, e& E$ U* n
  425.         CE_Low();                                /* enable device */
    + h: ^4 g/ Z) A0 L+ [4 z* Z
  426.         Send_Byte(0x04);                /* send WRDI command */4 H6 O3 x. Q# E9 f! e8 i
  427.         CE_High();                                /* disable device */
    2 Q& J2 @  o/ e  k( w
  428. }
      i  `9 a0 U" Z; v% z
  429. 9 U! }. y( x- J2 v  Q3 L
  430. /************************************************************************/9 m8 v  g& C8 E' j1 P! L6 s6 ?, e
  431. /* PROCEDURE: EBSY                                                                                                                */9 _8 G0 q9 m! M- X9 P* q/ o: u; w" C
  432. /*                                                                                                                                                */
    ' A, q! u5 `$ E/ H. N3 O
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    . S! ]% H/ u' m: |. P! T
  434. /* programming.                                                                                                                        *// r  d! Q0 e% V9 h- Q( u
  435. /*                                                                                                                                                */
    6 ]( d/ L7 w8 L- X
  436. /* Input:                                                                                                                                */
      C  r' n2 n- q( k
  437. /*                None                                                                                                                        */
    6 Y# u. }' u! G# ^; I$ b2 p
  438. /*                                                                                                                                                */* T- T* {/ Y  ~4 _- U) T
  439. /* Returns:                                                                                                                                */. Z, K0 j% h3 A" P
  440. /*                Nothing                                                                                                                        */
    7 G6 s- c; c7 v2 d4 Z, ?4 a  i
  441. /************************************************************************/
    9 z6 B, Q3 X3 l1 H, J
  442. void EBSY()# f7 ^9 X. i0 B$ R8 u+ |2 [
  443. {" m3 \# L, }) x; \, Q3 o
  444.         CE_Low();                                /* enable device */
    7 I, C  H) |* \9 t2 t+ r; N  |
  445.         Send_Byte(0x70);                /* send EBSY command */  \3 p- o# c2 A% Z9 p" j
  446.         CE_High();                                /* disable device */
    " {. O! \  ~" k; N0 Q
  447. }( A& U7 \: G' V# W( W6 O/ K5 w

  448. & y, n2 w( J2 @% V! ?# e- ~- w3 c+ c- n
  449. /************************************************************************/( v7 b2 c3 \( L4 Z( B1 x
  450. /* PROCEDURE: DBSY                                                                                                                */0 O  \" Q7 `! o
  451. /*                                                                                                                                                */, y- g: \: t/ [! g8 a. p( r
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    . \, i/ a; {2 m
  453. /* programming.                                                                                                                        */
    / w( z  Z: T% ~% B  b/ h0 I
  454. /*                                                                                                                                                */7 t8 t: ^; E1 a1 P$ m2 A
  455. /* Input:                                                                                                                                */
    ( v$ P, d7 v4 U' ^0 A& X
  456. /*                None                                                                                                                        */5 I- P- b. z( i3 _2 _
  457. /*                                                                                                                                                */2 n$ X6 W1 n* _
  458. /* Returns:                                                                                                                                */9 @0 o! r. m4 Z2 c4 I
  459. /*                Nothing                                                                                                                        */
    . ~1 r/ @3 R; m3 y) {/ v
  460. /************************************************************************/
    # ^& C8 m+ {* h
  461. void DBSY()
    % _% }0 P# t) p! Q4 h
  462. {
    3 r% l* e( j! ]5 t% E/ ~9 P
  463.         CE_Low();                                /* enable device */" m, c, L: w9 l5 r
  464.         Send_Byte(0x80);                /* send DBSY command */
    6 A- w# t& k3 P' s: d
  465.         CE_High();                                /* disable device */
    ( W2 ?9 p: j7 j
  466. }
    & g8 n4 g  G3 I1 @4 n

  467. 1 `( o" l5 s& b4 `1 r
  468. /************************************************************************/: z5 m7 k9 N; `4 I; W
  469. /* PROCEDURE: Read_ID                                                                                                        */
    5 Y, t. h3 }  _6 f
  470. /*                                                                                                                                                */; Z! M1 T" L) m: i
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */* d" I8 \  [8 y! {& a" c" T
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    ' U! E5 i; k# v+ P3 m6 H
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    / l  S$ ?, t9 M) O$ L4 j$ @9 W
  474. /* whether the device outputs manufacturer's ID first, or device ID         */$ y, j' h7 K9 R/ J3 P5 T
  475. /* first.  Please see the product datasheet for details.  Returns ID in */! @8 |! z. s( q! }. _# z
  476. /* variable byte.                                                                                                                */
    1 G2 z. Z8 o; U% V3 l7 V' ]
  477. /*                                                                                                                                                */
    . m7 {; e5 p# J/ ?% ?
  478. /* Input:                                                                                                                                */
    , e$ g/ u& n' s3 T
  479. /*                ID_addr                                                                                                                        */
    * a6 R# _+ v2 J% t
  480. /*                                                                                                                                                */3 ]5 M7 H9 q! v1 }
  481. /* Returns:                                                                                                                                */) D$ \" ^* n# C4 h5 F
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */& {$ w* W9 V& ]  f2 b- B
  483. /*                                                                                                                                                */" e' M4 D- ]5 n3 a; a' n# `/ M- {
  484. /************************************************************************/) d9 ?7 {( [1 a& @$ o- k
  485. unsigned char Read_ID(ID_addr)% @+ h: d% ]& O+ z2 T
  486. {
    7 f+ G5 ]9 G4 C5 U2 O; P4 |
  487.         unsigned char byte;
    & L0 X7 I9 X5 Z! @, h  e+ c
  488.         CE_Low();                                /* enable device */
    ( j7 L' l) R9 z5 }
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    7 C  N5 b8 u) \1 ^7 s8 \: z
  490.     Send_Byte(0x00);                /* send address */
    ! b0 B: p% |( m6 C1 Q
  491.         Send_Byte(0x00);                /* send address */
    9 Q; N3 p6 F& L' |- g
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    ( H- o0 }0 _& k: v( F
  493.         byte = Get_Byte();                /* receive byte */- a+ ]7 i- m- M/ I8 m
  494.         CE_High();                                /* disable device */
    5 M" X0 e3 t, W1 [
  495.         return byte;
    : P6 e3 C1 |+ ^# R
  496. }; c5 }+ O  C3 o7 ~

  497. 2 J( x4 m# R3 d" L) X/ n
  498. /************************************************************************/
    4 @6 M% E" o* V4 S: F; c
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */+ v% O/ z6 Q$ F6 a
  500. /*                                                                                                                                                */0 _* c9 t- N3 O& x+ r8 X8 N( f' f
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */6 M# Y% Y& B4 B3 S( P' Z" N; d% d
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
      M: U* E: \& V1 n; g+ O3 I
  503. /* Please see the product datasheet for details.                                                  */: W) z" ^0 n& ~4 C% U( o
  504. /*                                                                                                                                                */4 m- O; p# g7 {9 G# I; p. P
  505. /* Input:                                                                                                                                */" n" ?* w/ S: q% k
  506. /*                None                                                                                                                        */
    1 ^+ [8 m6 X0 X$ b0 T
  507. /*                                                                                                                                                */
    % I& P5 Z: `  Y5 W
  508. /* Returns:                                                                                                                                */! J) P; J! [. Y7 z3 a2 m6 ~! @
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    / m+ ^& ?/ _8 {$ v
  510. /*                 and Device ID (8Eh)                                                                                        */2 C: s3 ?+ x) ~) k% x
  511. /*                                                                                                                                                */
    # X* a, |' f% y6 g
  512. /************************************************************************/
    5 D5 q0 e' A. k& H6 r
  513. unsigned long Jedec_ID_Read() $ \$ z$ J) F1 m5 [' H, w6 m0 B; }
  514. {
    : l- f. i$ k) a% D7 e$ p3 v
  515.         unsigned long temp;7 b/ H% F& I' S" o
  516.         2 [4 Q* M9 Z9 h& ]1 B  Y: ~
  517.         temp = 0;5 K) T; E8 |  N5 Y# {
  518. ' R. v+ n7 b) B6 a/ J
  519.         CE_Low();                                        /* enable device */
    2 o; ^) n3 ?+ Q
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    0 H1 K- W7 I9 E7 \. _- W
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    1 K& m/ M$ Q; T+ v; K2 x' L# h
  522.         temp = (temp | Get_Byte()) << 8;        5 ?' S- [+ H& ^' v: m4 p
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */# e7 n; R5 H1 b7 @8 ?" u
  524.         CE_High();                                                        /* disable device */
    / g0 ^  G" B  q4 o9 R6 I% _- z* m
  525. + Q+ s& A3 p" ?$ I( I
  526.         return temp;  F% L; E, }0 L; ]6 a8 U1 M: X: j3 {
  527. }
    3 G2 ~2 b5 l* j! p

  528. : H, S8 Y- U' r" _7 x4 |
  529. /************************************************************************/& b3 y3 q6 S4 P8 O1 r
  530. /* PROCEDURE:        Read                                                                                                        */' Z+ ?; R; \0 Y+ {- ^$ A
  531. /*                                                                                                                                                */                  M' B! Y  G4 |2 Q* \9 j& Z
  532. /* This procedure reads one address of the device.  It will return the         */
    % i5 M! p1 g' S
  533. /* byte read in variable byte.                                                                                        */3 W3 N( ]. \* V+ G: _
  534. /*                                                                                                                                                */
    ) k) ^2 [3 I$ i! ?1 k, y; Z
  535. /*                                                                                                                                                */
    . \( s& ]" n9 O% N) U
  536. /*                                                                                                                                                */( }8 s9 f# s* d% I; `2 M# \+ i9 e
  537. /* Input:                                                                                                                                */; T' [7 G- j. k, I( u
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */! d8 H4 s9 e. m+ w: _5 t
  539. /*                                                                                                                                      */
    + F" R+ M! h4 K0 V
  540. /*                                                                                                                                                */
    % ~1 M# B0 _  P3 V' V
  541. /* Returns:                                                                                                                                */
    * P3 c* x6 c4 z
  542. /*                byte                                                                                                                        */8 }  c$ ^5 N  H  m
  543. /*                                                                                                                                                */
    $ z* R' S$ s: J( A$ l
  544. /************************************************************************/
    & H( y3 x- W9 P+ E3 c
  545. unsigned char Read(unsigned long Dst) # s0 N: f  K/ |  K1 y, {
  546. {. z; t4 k9 w/ @9 D2 s
  547.         unsigned char byte = 0;        " u0 j( p4 r  X- i. ?% m

  548. 2 s4 M, `" y& R
  549.         CE_Low();                                /* enable device */& O8 J- D, R& n7 |! ~7 O
  550.         Send_Byte(0x03);                 /* read command */! R. F: |  `) _/ S
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    " J$ j  P) E3 j9 ]1 P3 P& [
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));  W  J0 q9 l6 ]- d, i
  553.         Send_Byte(Dst & 0xFF);7 Z* F3 l3 Q4 \/ |, v4 z
  554.         byte = Get_Byte();! u' i4 W( l5 G
  555.         CE_High();                                /* disable device */( j' q1 p5 \3 i$ p5 e+ Z: e. Z) G$ ?
  556.         return byte;                        /* return one byte read */; a% S' i7 R- \' C1 Y8 X
  557. }) T3 Z+ F' z+ l' R
  558. ( ]" H+ h, m1 l" D( C
  559. /************************************************************************/& m$ j0 f# q( H# e& w+ Q0 [
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    . n0 l9 n- d7 ?* Y& I; Z
  561. /*                                                                                                                                                */               
    3 w9 n& @- K5 F; c2 C7 Y/ O4 r/ m
  562. /* This procedure reads multiple addresses of the device and stores                */
    ( `; m  A9 H' k/ W& Y, x/ z. T' E- n
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    2 b' d2 _; L: h& W. f' H8 P6 D
  564. /*                                                                                                                                                */
    ! S3 k% ?) |% ?) y. Z
  565. /* Input:                                                                                                                                */& ?: j: N0 `, }/ M: Q* ~: m
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    % m; R( L1 h& K1 l$ X, Y7 [
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */- b  `" [5 [1 ~9 g( m
  568. /*                                                                                                                                                */
    0 z' u  f) l  D5 a4 u
  569. /* Returns:                                                                                                                                */
    7 j$ I, _5 e+ `* e4 ^# d
  570. /*                Nothing                                                                                                                        */
    0 e) W: ^% y8 O) }9 [
  571. /*                                                                                                                                                */# }9 S3 c; X$ r+ F
  572. /************************************************************************/
    " k& m  z% U" w2 P
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes); `! Z% n( F0 Y+ ^
  574. {
    - ]4 X, ^, K# p* |- P3 ~
  575.         unsigned long i = 0;
    ( `7 c" _" e; D6 p/ C9 t5 d  |
  576.         CE_Low();                                        /* enable device */
    ( Q6 ^* F6 E8 N( A" t* Q# ?4 S0 Z
  577.         Send_Byte(0x03);                         /* read command */! u# ~: D- |; Q. S0 ?
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    5 \4 F* _( ]4 H* G
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    1 V+ {. U* b/ y: c) u$ J: \
  580.         Send_Byte(Dst & 0xFF);# Y  U6 @' {7 \) v  R
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    $ ~* N: c; a- L" c6 S
  582.         {
    0 [! r! j! d8 U$ S3 L
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */7 y% i4 E# S! K  t0 G
  584.         }
    # W- q4 _; ?) U
  585.         CE_High();                                        /* disable device */
    - P7 X1 [: o0 F1 l0 ]
  586. 2 C4 y+ `0 a  m
  587. }# d7 l- @7 ^2 N0 \7 o1 I

  588. # l3 [3 I+ U- Y5 X( j* H, U3 N
  589. /************************************************************************/
    ! \& p: i! g! H
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    / i5 B5 k+ S8 z
  591. /*                                                                                                                                                */                + C. v) C. Z* {7 I* B, n
  592. /* This procedure reads one address of the device.  It will return the         */4 v2 C: D& s/ s% r
  593. /* byte read in variable byte.                                                                                        */
    1 ]# Y4 w' E" p8 t" M+ Q' @
  594. /*                                                                                                                                                */
    2 ]0 a" N  i; w# d' @
  595. /*                                                                                                                                                */
    9 i1 w  O& J$ i
  596. /*                                                                                                                                                */
    , c+ k* Q' |+ V! e$ y) U+ C+ d
  597. /* Input:                                                                                                                                *// X, G2 X& j9 k+ Y5 Q' Y$ z9 H) ]
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */. p/ p/ O$ m6 g) H. g- f
  599. /*                                                                                                                                      */1 f: U: r) Y5 @% u
  600. /*                                                                                                                                                */
    9 U% q0 b" |; ^0 _' T
  601. /* Returns:                                                                                                                                */
    : R, O4 y' L8 Y( o
  602. /*                byte                                                                                                                        */
    ; L- n+ V: |  u; G
  603. /*                                                                                                                                                */6 I+ y2 }, e8 i( {7 t
  604. /************************************************************************/7 Q7 D$ N' a, `) C* W) o
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    6 s. S: n5 u, l- f$ u3 y0 {
  606. {$ Q; a; F& K" I9 a( G' g
  607.         unsigned char byte = 0;       
    ( l$ z& h3 B; [
  608. % [; S5 o- P, L( y
  609.         CE_Low();                                /* enable device */7 E0 r8 ?  M+ W( |$ {+ \3 E
  610.         Send_Byte(0x0B);                 /* read command */
    $ H2 G, C; U+ N. Z4 q" H  G
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    1 V% C; q  k4 @+ Z6 p7 K
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));" ?' R9 i/ X' V; I9 U. j
  613.         Send_Byte(Dst & 0xFF);
    1 x! Q" R5 O, }
  614.         Send_Byte(0xFF);                /*dummy byte*/
    - ~5 m  c0 g1 p! a" F! O/ N) X+ Z
  615.         byte = Get_Byte();
    : }, m5 T- }$ ^  w. b; S+ y2 w
  616.         CE_High();                                /* disable device */! C7 w+ ?6 ?( B  M5 }
  617.         return byte;                        /* return one byte read */+ x( Z$ L1 k# E' H$ M) d8 ?
  618. }
    4 c, H# D8 p7 Y7 j/ I+ {" {

  619.   a2 X. g. V1 U) }, c
  620. /************************************************************************/: W  k2 F! g4 V/ k1 A7 j2 e
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    8 z6 R, e* m( r
  622. /*                                                                                                                                                */               
    7 s; T, T" M( E* x9 b" n& z
  623. /* This procedure reads multiple addresses of the device and stores                */
    & L  f$ k7 N# n( f
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/- s% J$ z% T5 U! ]* v8 Y  O( _1 M' ~
  625. /*                                                                                                                                                */, }4 T4 c/ ^0 d' C4 n' g9 J
  626. /* Input:                                                                                                                                */
    : A) G, P* N. C3 b9 I1 I) L' {0 q
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * L: O+ S$ j& _) f6 v% l& n1 C
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    $ [+ W& J( }! h) u
  629. /*                                                                                                                                                */9 C9 @- v' q; c: }. Y: _
  630. /* Returns:                                                                                                                                */
    2 k3 h- `$ e- J+ w! R' M) q
  631. /*                Nothing                                                                                                                        */
    + ^2 f& A) O  O" R% E
  632. /*                                                                                                                                                */
    : K/ y. R; p: i: g, g+ d
  633. /************************************************************************/
    " C9 v1 {# [3 d1 E8 X
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    % k& P) J3 H, \& Y* U# F! ^1 A; N
  635. {
      T/ N( ]6 d  `- N
  636.         unsigned long i = 0;# o: ~% A7 Q4 w% G2 D
  637.         CE_Low();                                        /* enable device */' K& M) N0 g* i8 @/ h8 V
  638.         Send_Byte(0x0B);                         /* read command */( |( r; J5 Z. Q5 X6 N
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ! p) O; \. }- J5 g' h3 _
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));1 C% `" D4 b8 D; F% f' h( |! w
  641.         Send_Byte(Dst & 0xFF);
    ( |7 F' N( n# w* W9 Q& W
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    5 `3 W8 a! a* \- L
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */; W; f3 U2 y/ O+ {/ x
  644.         {$ M: w- L# O* D+ x
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */$ _, E- H; z2 Y8 n; G+ F  q: {
  646.         }& _# ]! W2 t6 Y& ?4 j
  647.         CE_High();                                /* disable device */5 b) z$ O$ l, G- }+ W( Q8 Y
  648. }
    + `& `9 z; u" g8 v

  649. - s3 k1 n; ]# `+ b! b( _) n
  650. /************************************************************************/
    ! l7 {0 q' K" L
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    # d2 O6 s' |9 N" n
  652. /*                                                                                                                                                */
    + v0 L$ B9 a4 I8 r+ ~, K$ z
  653. /* This procedure programs one address of the device.                                        */" Q6 o' j+ ^; q1 F  z8 y
  654. /* Assumption:  Address being programmed is already erased and is NOT        */, @8 H% W% Q% U7 w. {  a+ L' j
  655. /* block protected.                                                                                                                */* @# |0 U% k  g* M# t+ I. Q  v) I
  656. /*                                                                                                                                                */
    % K/ y" }8 S8 F5 V# F8 k. C! r
  657. /*                                                                                                                                                */" z5 y' p& b- K
  658. /*                                                                                                                                                */! }" z8 X0 F# @1 ?
  659. /* Input:                                                                                                                                */) v" h; B- }% Y$ @2 O  l
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */( n1 Y% \1 \* H9 o
  661. /*                byte:                byte to be programmed                                                                */
      i' L& D3 J# s
  662. /*                                                                                                                                      */
    9 z) r* z9 T( F" Z6 e: a: g
  663. /*                                                                                                                                                */# _# Z8 X' p1 c' n3 V* B
  664. /* Returns:                                                                                                                                */) A3 U" u$ N% d* U2 m% O2 w) g
  665. /*                Nothing                                                                                                                        */5 L: o7 L- ]* s5 n  I! ]; e
  666. /*                                                                                                                                                */2 W) u  ]! c- o' S3 ~6 f5 g$ d
  667. /************************************************************************/
      p( O; Y9 c" N$ F0 B% T3 f
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    , v, o9 q' X; b7 F& ~3 J! W
  669. {
    / E, B6 X+ z% W4 j6 J
  670.         CE_Low();                                        /* enable device */! `) u: R& }9 z) m7 d5 Q0 u
  671.         Send_Byte(0x02);                         /* send Byte Program command */- r9 s; |* o# O8 e; _' N
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    3 W- u; K2 Q4 @) N' L5 ~* }8 ^0 I* {
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    8 s# i/ H( ~+ _( z
  674.         Send_Byte(Dst & 0xFF);: E+ A* x; K$ u% C. @' x8 a
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    7 y7 j* v$ d8 C* S8 L9 W
  676.         CE_High();                                        /* disable device */9 S4 x8 ?# {$ F% G- D, M" _2 v
  677. }
    . S% ?0 _7 @+ V6 r0 Z# a2 ]

  678. # k/ B3 {! e0 Q
  679. /************************************************************************/
    4 E5 ?/ F. W- s( ?6 n
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        *// j/ W( Z  q! a. M* n( O
  681. /*                                                                                                                                                */
    6 j$ N4 g6 A# u
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    ) k8 K2 }9 }! D* Q$ b) ]# E
  683. /* the device:  1st data byte will be programmed into the initial                 */
    1 M2 a* r; R. n! }
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */2 ]) R8 x( H: J+ w
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    3 {: B5 O8 x0 F/ z  V3 f
  686. /* is used to to start the AAI process.  It should be followed by                 */- {( T9 p. b9 o) f3 ~
  687. /* Auto_Add_IncB.                                                                                                                */. V! P, n7 L+ X) p1 V" K) |
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
      M! L) o: \2 r/ {. m
  689. /*                                block protected.                                                                                */* H) S  i( r0 e* j; u
  690. /*                                                                                                                                                */
    9 m6 K0 L3 H2 W
  691. /*                                                                                                                                                */
    2 w# `3 n( B8 n% Z* F, |% k# Q0 M! s
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */8 H6 n  L8 o' J
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */7 `+ e' b; f+ ~. ^
  694. /*         unless AAI is programming the last address or last address of                */# |. }' m8 T: \' ]& o/ [
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    ' C  Y; e1 }  A5 j* o
  696. /*                                                                                                                                                */
    : f$ L  ]. Z+ ?, `  W% M
  697. /* Input:                                                                                                                                */$ K# l. ^. G! U, C* j9 ^7 v
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    1 e6 e5 M# S/ i4 c
  699. /*                byte1:                1st byte to be programmed                                                        */' Q8 \  P5 M; D, c) H' b
  700. /*      byte1:                2nd byte to be programmed                                                        */
    / `; v, l% u2 Z
  701. /*                                                                                                                                                */
    ! ^8 W0 g1 J- o, L
  702. /* Returns:                                                                                                                                */
    % v6 z$ U: V1 M& L* E$ \
  703. /*                Nothing                                                                                                                        */1 P) Y5 W1 C" S5 Z4 y7 y$ a
  704. /*                                                                                                                                                */9 `" a& W; w+ Z9 G. l) a
  705. /************************************************************************/! S6 c+ u1 V) G8 Q! t( x0 _
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
      p1 [5 K9 b  N3 }( i
  707. {5 B8 B7 D# `3 `! p  l% d( W
  708.         CE_Low();                                        /* enable device */$ j8 [: W) T! o( i, X2 J
  709.         Send_Byte(0xAD);                        /* send AAI command */
    / o( F+ R  D) c6 `& }; u
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */# X9 e1 g- A! A% Z9 G
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));! O7 _' N! V6 r( b  h1 Q# J$ C
  712.         Send_Byte(Dst & 0xFF);
    8 n2 G0 m, I- E" V
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        0 h0 Z. A* m- {
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */5 \* v7 E: w$ M$ T9 a2 ^6 \: Q
  715.         CE_High();                                        /* disable device */# E5 H6 I8 N, t( i9 P) ]
  716. }
    ! j1 D% P# c. h7 ^- `( D
  717.   x4 d9 }5 c  R, n/ Y7 q4 A. o
  718. /************************************************************************/4 X$ O# E% G$ s4 J3 Q: A4 v5 Y' |
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */% H2 J3 @5 S3 h1 q9 `& V% D7 q
  720. /*                                                                                                                                                */
    4 y: T0 H- W6 @' l* [/ u9 j, g
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/6 m; V: K0 G7 k/ Q- ?) h1 t8 p- B
  722. /* the device:  1st data byte will be programmed into the initial                 */
    * V: d( u/ H* g
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */, H9 ~+ v, N2 @# u1 l2 R0 z  P, D. l
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */3 [5 d' r! A/ l9 d
  725. /* is used after Auto_Address_IncA.                                                                                */9 h; p6 [  [  y7 ~$ B1 E7 z( _* o
  726. /* Assumption:  Address being programmed is already erased and is NOT        */& F5 @! r0 n" O2 D  v
  727. /*                                block protected.                                                                                */
      s. x/ P+ ^( \7 s( E5 ~/ E
  728. /*                                                                                                                                                */3 v8 W* A, |( {6 g( @
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */3 n- _3 H% b5 a% j/ l
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    3 j8 X4 f  @0 v7 p" |" U7 ?- {
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ' g; @) u& }, _2 A& J$ k
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    1 r7 a6 Z* L  N, J4 a/ v
  733. /*         last address of unprotected block, which automatically exits                 */1 [9 ^% o' c% u8 X0 {* H
  734. /*         AAI mode.                                                                                                                        */: Q8 I" r. D3 B8 V
  735. /*                                                                                                                                                */
    ) f/ x3 v; V+ H# E1 q0 d* U5 j( z
  736. /* Input:                                                                                                                                */* p) ]' k6 J% R) y  ?
  737. /*                                                                                                                                                */
    ; p+ |% X' v0 o2 c8 o1 q$ b1 V; W
  738. /*                byte1:                1st byte to be programmed                                                        */' s& d5 V% P  s* s6 X
  739. /*                byte2:                2nd byte to be programmed                                                        *// @9 h" J# U; j0 J& R
  740. /*                                                                                                                                      */
    : R, h. r) g' a- u* i
  741. /*                                                                                                                                                */
    5 B) E$ s8 o. N
  742. /* Returns:                                                                                                                                */# o# p/ Y! ?( j1 f# T- h
  743. /*                Nothing                                                                                                                        */+ w- T% }* i' N0 m
  744. /*                                                                                                                                                */6 y  l! w, X# s$ v
  745. /************************************************************************/  a" `) X" H- Y7 Y( ~
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)7 ?* u* @2 ^- i( ]( q* z) a- w
  747. {
    4 ?2 U& b$ V- G- L
  748.         CE_Low();                                        /* enable device */
    " x* o* W. h' q( P. o
  749.         Send_Byte(0xAD);                        /* send AAI command */8 l* x+ S: Y7 p3 b6 v2 U: w' e9 i
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */4 y3 ^, J( Z3 w, ]! H$ m& p
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */7 d9 d, j3 z; L2 @! ~' M! b
  752.         CE_High();                                        /* disable device */
    - b* D; ?7 M6 T5 b7 ~! ?! J
  753. }" _2 H4 }" M) z: w3 N6 J& `

  754. 9 ?! f1 I/ ~( B" u1 z
  755. /************************************************************************/
    ! V, f  J& s; j. N# _7 m# L# ?
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    & `  R  F) X/ |! \* t, F7 I+ \
  757. /*                                                                                                                                                */
    $ W6 l0 l( t& ~# M! B# F
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    : \7 Y- e" ]. ?7 }
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    $ i# |1 r! }! p* P
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    6 `/ m3 [. {, a7 ~9 a( g
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    " B0 U+ E( N; W' R0 {0 N* I' H
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    : B: C; C# s. z7 N8 [
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */( B8 W* G6 `) `% _3 r* F, P
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */1 f, r% c9 U5 Y  U+ S& N4 y) u
  765. /* Assumption:  Address being programmed is already erased and is NOT        */! s% D* _/ S- b
  766. /*                                block protected.                                                                                */( {5 s) |* G4 }1 `3 ?; J3 G- f
  767. /*                                                                                                                                                */4 f; o' J  I# |' B& Z- `3 W! V/ X
  768. /*                                                                                                                                                */6 J# S& K+ S+ \8 h/ t3 `
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    + A6 e. O  @' Q$ j
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */! D& H8 y" D5 ?
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */! z; L" X6 o- R- s9 d, L
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    3 R! S, ]& Z* C- N- i
  773. /*         last address of unprotected block, which automatically exits                 */, \3 `) t  c. p1 C  k5 C
  774. /*         AAI mode.                                                                                                                        */
    8 k# c+ ^- H, W1 n# r
  775. /*                                                                                                                                                */
    ' i+ V; l, i3 z+ k4 t
  776. /* Input:                                                                                                                                */9 V+ [! W: f7 L
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */6 b+ e. Q7 d- a1 N
  778. /*                byte1:                1st byte to be programmed                                                        */
    + _8 B3 M# g7 o+ N. @2 Y
  779. /*      byte1:                2nd byte to be programmed                                                        */
    4 ]  i  y) L% k6 z& Z+ C1 \; h# c
  780. /*                                                                                                                                                */7 p1 C8 H9 k/ ~0 F
  781. /* Returns:                                                                                                                                *// y' a& i/ ~7 H; U+ A# [+ g) \
  782. /*                Nothing                                                                                                                        */
    7 x- v" s3 Z/ s7 Z9 ~7 G
  783. /*                                                                                                                                                */8 n( L, g9 v( R; K# _. ?. a
  784. /************************************************************************/  I. N1 \1 v5 h, p% [
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    8 D8 f$ A' `( D  e# ?( r- ^
  786. {
    ' x: X9 q, D( K5 y
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        * Q8 M* g3 h2 C+ c6 m( j" X

  788. 0 q9 K6 s$ m4 f1 X
  789.         CE_Low();                                        /* enable device */
    5 M* l! {% c9 K  ~/ V" w8 c
  790.         Send_Byte(0xAD);                        /* send AAI command */
    , u- M( n& h: E
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    " X* k1 X  w7 {" t
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));3 g. c2 Q& ~5 P% [' F- T& _9 @
  793.         Send_Byte(Dst & 0xFF);
      N. F8 Y1 p% U3 b; h5 M. V
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    ; M  B$ l7 S2 ]: I5 z2 B
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    , V- _7 D0 d0 N7 p1 e1 {/ Q
  796.         CE_High();                                        /* disable device */+ P' {0 g- X: F0 b; M
  797.         # M4 P: M1 F. U% n
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */& R' O+ r1 i' |2 l) K( N' _$ ^+ }
  799. ' w6 f0 G$ d# X/ {$ L$ w
  800. }* V3 W  u# i, p5 k/ Q9 L9 w6 |

  801. 6 |! ^  B/ `" L7 a: D0 r+ r
  802. /************************************************************************/* W3 h$ S0 \: X
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */" g+ O$ h& B- d) H2 P& K/ c
  804. /*                                                                                                                                                */
    / |2 f* T! C/ ~; S9 M( s1 S! m
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */, v0 `" b  p4 d7 T; q* ]
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    8 F" K8 j7 H; a* w
  807. /* AAI programmming is completed.  It programs consecutive addresses of */5 L( {; P% E; o2 q9 a) O9 D' [& t; g
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    # E: m' O8 d3 M* e$ B2 G
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    # ~! }" O% S, G2 w
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    8 x0 x" K' C* z+ k/ }( \: f
  811. /* used after Auto_Address_IncA.                                                                                */1 e1 v& E* E, a3 E2 r
  812. /* Assumption:  Address being programmed is already erased and is NOT        */3 Q6 a7 o: ~) d% k2 q6 s2 `
  813. /*                                block protected.                                                                                */
    2 i8 }  L5 \, _& w) g: K/ m
  814. /*                                                                                                                                                */9 `9 ]7 [2 E( R9 I. E6 v. e. C$ ^
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    & E$ F, b+ f) |  p6 @
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    - Q* x* N( u  @: G
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */1 ~: b2 t4 N, N" j+ H
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    4 ^& H0 ]3 i& B7 j* o; N
  819. /*         last address of unprotected block, which automatically exits                 */
    # Z8 g; L" i9 ^. @
  820. /*         AAI mode.                                                                                                                        */
    ) \% i/ L: \3 w. n
  821. /*                                                                                                                                                */$ r( e! p( q1 B# ]! R% t9 w
  822. /* Input:                                                                                                                                */
    ) A9 t5 t- |5 L6 L7 r
  823. /*                                                                                                                                                */
    , k0 S. s6 D) p! [* x/ o3 y( A
  824. /*                byte1:                1st byte to be programmed                                                        */
    ! P# W$ N' u0 z; s% c# N! j
  825. /*                byte2:                2nd byte to be programmed                                                        */
    3 V, U. S$ G9 H$ i
  826. /*                                                                                                                                      */+ L1 u: w# h1 ~& F* _
  827. /*                                                                                                                                                */
    3 D+ M7 u% g- a* [( d. p
  828. /* Returns:                                                                                                                                */% V3 p3 s/ X7 z; @. B# }6 g  @
  829. /*                Nothing                                                                                                                        */
    8 H: {3 b* G0 P$ r. G* H
  830. /*                                                                                                                                                */
    : J$ L- e1 C  ^( z3 r
  831. /************************************************************************/
    ( |' x  v% d- y; i) u$ H- Q
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)+ j1 z" J7 L7 b7 w9 j2 p9 @) Q
  833. {
    ( E4 F; ~. {$ G1 i" b( T$ G7 L
  834.         CE_Low();                                /* enable device */
    + P& u9 k0 M1 Y2 G6 d. t$ q
  835.         Send_Byte(0xAD);                /* send AAI command */
    # ?$ N' K1 }7 ~: c" e
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */9 L: F4 t4 I4 ]& m  ~
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    * G2 r' ^5 I* u) m" x5 K
  838.         CE_High();                                /* disable device */
    / C* `8 I: K/ N( B
  839. - M- E, y6 J* S# [+ M
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    0 o, i4 l! H5 }* l& Y
  841. / T+ Y" c9 h- W, I+ ~
  842.         WRDI();                                 /* Exit AAI before executing DBSY */. y6 Z( f  w' t# J
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    + L& `1 j, G$ j; ~8 g- C: |8 K; A
  844. }( I: z+ ]% n3 O3 n% N2 ^

  845. & N+ J2 Q& [/ ^; x& _/ U
  846. /************************************************************************/
    5 T& B, t. [7 ?( u
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    : }: j$ m4 T' G1 u
  848. /*                                                                                                                                                */- c3 _+ F1 ^4 Q! j  {! }1 ~
  849. /* This procedure erases the entire Chip.                                                                */- L6 T& {" b/ f" o; x1 m/ N/ Z
  850. /*                                                                                                                                                */
    ( J; W' B% i1 m1 F% l5 `
  851. /* Input:                                                                                                                                */
    4 z. M- {! Z' r0 N, P0 `* y
  852. /*                None                                                                                                                        */
    $ _& X0 W9 |) {" R9 N; w* k8 r
  853. /*                                                                                                                                                */. ?! `5 w. F4 z( S8 d. `% l/ I
  854. /* Returns:                                                                                                                                */
    5 u6 E6 s! I- g, I* T! B) A; h
  855. /*                Nothing                                                                                                                        */
    * U* _2 I# C3 Q; F8 Y% Y  ?$ B6 |
  856. /************************************************************************/
    0 I9 Q# {0 T# H# H# G/ _
  857. void Chip_Erase(), I, [- V) `$ C+ n
  858. {                                               
    ! Q$ d; b# u2 g- b
  859.         CE_Low();                                /* enable device */  g% i: L8 Y& a
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */6 F& @5 a/ J8 C$ t0 w7 M
  861.         CE_High();                                /* disable device */
    * r, F  l( k% y; s
  862. }
    $ @& c( ^" h% r2 c

  863. + T% X' v+ m6 E3 H
  864. /************************************************************************/
    / u) ]- N, U, g+ }# @; J
  865. /* PROCEDURE: Sector_Erase                                                                                                */1 d: b7 U5 [. b) o' R) s
  866. /*                                                                                                                                                */
    5 I  i6 C# C6 |& T) d. i2 Q6 x/ ^. Q
  867. /* This procedure Sector Erases the Chip.                                                                */. `; [& Q& D5 g* j5 D- x
  868. /*                                                                                                                                                */
    1 [5 h9 u* N1 ?! g1 F6 |) A9 X
  869. /* Input:                                                                                                                                */1 x' u) O+ n+ L; J5 Z  w
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ; |3 `4 z$ f* Y) A& Y& |6 }
  871. /*                                                                                                                                                */
    / Y- k1 o/ h$ z4 N' n
  872. /* Returns:                                                                                                                                */- ?1 e6 b$ ?9 E) V+ U5 }1 V
  873. /*                Nothing                                                                                                                        */& G8 y2 @* E1 u3 G' q3 |, C
  874. /************************************************************************/; }7 o7 w: |4 \0 @
  875. void Sector_Erase(unsigned long Dst)
    # [& l1 [4 s: {
  876. {
      o+ w' H/ \1 F! i# V: i
  877. ' ?7 T4 G8 p& e1 z
  878. 7 a# t2 m1 r0 Z% i! m& z/ R" `' w
  879.         CE_Low();                                        /* enable device */
    7 d9 C0 m/ c; x4 M9 ^
  880.         Send_Byte(0x20);                        /* send Sector Erase command */9 K, S3 Q, v: `
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */( I0 U) d. ?2 U7 }$ s
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % H% [& E& L& E- N* G5 N5 e
  883.         Send_Byte(Dst & 0xFF);
    : P* U% ?# b  r: G& T9 O  ?
  884.         CE_High();                                        /* disable device */
    " h# ?2 u! x9 }( A
  885. }       
    2 E; u& \. j: r1 N, w& `' y4 Q
  886. + O; F$ Y1 J% e1 U" a, @
  887. /************************************************************************// r* z) r+ K/ m% R; t
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    - f. ^! V/ b3 ~  r+ [
  889. /*                                                                                                                                                */
    ) n( A! s! Z' L$ f9 X% ?! d
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */% d7 j: r6 ?- U8 I; ?
  891. /*                                                                                                                                                */  B" |9 h$ t% d* }
  892. /* Input:                                                                                                                                */  u* H$ j5 v* s/ r  }3 R& W( f
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    6 r* E1 f5 F0 \4 H& H5 S
  894. /*                                                                                                                                                */
    2 B0 k& A! f$ ^$ K$ p
  895. /* Returns:                                                                                                                                */
    , J' y3 D( R( u" R
  896. /*                Nothing                                                                                                                        */
    ) E) e. C9 _7 w8 W, ]) y% n5 V. C
  897. /************************************************************************/; q2 N7 s& Q+ Z, s# M" i( G
  898. void Block_Erase_32K(unsigned long Dst)
    5 K' b7 U3 P6 _' n( O
  899. {+ [1 T$ O! c4 f' ~
  900.         CE_Low();                                        /* enable device */
    ) |) s- C3 L' S" h6 e7 O% A
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    ! j% U$ |" u- v
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    & ~$ J% A$ \% {# ]; d
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - i, Y! c7 d, |1 {$ D
  904.         Send_Byte(Dst & 0xFF);
    ) B: D! P# K/ D0 `! S' v, S$ k$ d
  905.         CE_High();                                        /* disable device */
    ) E+ r2 k) {( V3 W" v: ?
  906. }
    4 L" i; t3 M0 g, P# o# s) [& }2 F
  907. 9 C( W3 r, c7 T: L' O; t
  908. /************************************************************************/- t0 k; s9 ~3 P2 i1 o
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */- b: s( ~; R! C( \$ I* _/ {
  910. /*                                                                                                                                                */9 c$ m' @  ?( ^
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    # m' q: T9 Q) m8 e9 F7 M
  912. /*                                                                                                                                                */: e) n9 J6 N' k$ m- \
  913. /* Input:                                                                                                                                */
    ; `/ ?0 e/ C2 I! B0 N
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */" V2 g/ Z; h- n; H8 M
  915. /*                                                                                                                                                */) l* p6 i7 {( H! t: `, f
  916. /* Returns:                                                                                                                                */3 a: G6 Q: o) V7 I8 _
  917. /*                Nothing                                                                                                                        */2 k3 E& ]6 S1 x, ]% m
  918. /************************************************************************/
    + X/ m4 x0 M  l$ F1 s
  919. void Block_Erase_64K(unsigned long Dst)5 Q2 x8 D% }1 y0 y7 K
  920. {+ O) P: j+ {6 v$ L1 x2 I" S( _
  921.         CE_Low();                                        /* enable device */: }8 T' ], ?6 I$ [5 ]4 P9 J
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    " v4 G- R2 Q: k5 ~
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    1 |, n5 R, {( U
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));$ b7 K% R! v4 J  r% O
  925.         Send_Byte(Dst & 0xFF);
    3 L3 g* |, F4 R% Q
  926.         CE_High();                                        /* disable device */' \  @: P0 v# j( F, A
  927. }$ d+ f' y7 d+ K" g% `* E
  928. 3 r4 ^- `- P* I
  929. /************************************************************************/
    8 e8 ]# Z" ^1 l; F0 k: C6 N8 ~
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    8 j7 P" t4 u" E9 w8 @
  931. /*                                                                                                                                                */9 l7 W3 L( [: u  ]5 T
  932. /* This procedure waits until device is no longer busy (can be used by        */
    8 t) V& L% N2 {* [3 N& Y3 E! y! B7 u
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    1 P4 v. H5 L3 H
  934. /*                                                                                                                                                */+ ~4 t* j( g8 l( r( r; O$ r
  935. /* Input:                                                                                                                                */8 m7 j7 i* g5 w, P  Y7 J, ?
  936. /*                None                                                                                                                        */5 _; }; Z5 b+ k$ u( L5 ?
  937. /*                                                                                                                                                */$ `/ j* R/ Y  C6 ^" W2 K
  938. /* Returns:                                                                                                                                */
    : S( B7 f: c, X) ^* p0 z% v* x
  939. /*                Nothing                                                                                                                        */
    * n1 f, B0 O4 N) z  R0 U( S
  940. /************************************************************************/! d4 E. L' L  p, p
  941. void Wait_Busy()
    2 J) x) Y5 n7 T9 x! M, L' D
  942. {
      V) ^) N0 {1 @: N1 J( P& e
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    : e, L  }- \* s, B( Y% I3 _
  944.                 Read_Status_Register();
    / }% p: d* A! |
  945. }
      L% T2 R9 p6 \! R% p* H: G
  946. ' i, K( T/ m7 q
  947. /************************************************************************/
    + M% h6 z2 N1 a, j
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */1 X8 v0 [) M$ y6 F# l4 Q
  949. /*                                                                                                                                                */
    3 x2 {& V  ~3 |3 y/ |7 A& E$ n
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    # \9 i6 m, H3 A1 J# Z9 d
  951. /*                                                                                                                                                */2 E! u' S0 H' j0 C  ^9 b( s3 P
  952. /* Input:                                                                                                                                */
    : B0 |& s& X) i" k- v. E4 \! g& n
  953. /*                None                                                                                                                        */1 ?, W" U2 E6 }6 K
  954. /*                                                                                                                                                */
    , C' |( M' _  ?- ~- ~
  955. /* Returns:                                                                                                                                */
      E6 c; ?' P/ [4 ~% d6 b
  956. /*                Nothing                                                                                                                        */' R  a9 M& G1 R4 p2 H* U
  957. /************************************************************************/) c" w& _2 i: k0 r- n" O
  958. void Wait_Busy_AAI()& b2 y% \5 v0 P5 S
  959. {5 d4 v. k5 s6 C3 ^  s
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    ' _8 Z$ l9 G+ ]* R, p
  961.                 Read_Status_Register();* j8 ~- R0 _* ?2 p
  962. }: u1 z4 \) Z, t4 J, m+ Q

  963. ; R% ]3 ^6 q- S7 i( [9 R' e
  964. /************************************************************************/! [% S1 o5 i+ j- t
  965. /* PROCEDURE: WREN_Check                                                                                                */* i- H: a8 e3 Y0 C( `
  966. /*                                                                                                                                                */
    , ^% f6 n6 v7 z; O
  967. /* This procedure checks to see if WEL bit set before program/erase.        */. m6 p( K3 r: n/ J& Q
  968. /*                                                                                                                                                */
    6 R3 o/ M- m2 a- W
  969. /* Input:                                                                                                                                */
    1 `6 a5 |* i% w9 K3 P! r7 \
  970. /*                None                                                                                                                        */5 L0 ?, v; U, b$ G' y; a
  971. /*                                                                                                                                                */
    & F2 `* @$ }* z4 h9 r& C& E$ P1 l
  972. /* Returns:                                                                                                                                */
    $ U: v$ B7 o" x  S# y
  973. /*                Nothing                                                                                                                        */. N/ ]# Z) c, K: k. k# ^5 u
  974. /************************************************************************/8 z4 U7 [7 W- |0 o$ X. {% s4 V
  975. void WREN_Check()
    ; @9 d! [4 o, ^! q
  976. {! o& s7 w2 a" f& k2 |
  977.         unsigned char byte;
    ; U2 t5 ?( s  L5 K0 q
  978.         byte = Read_Status_Register();        /* read the status register */
    ( f8 R! ^3 ~# ?/ z* y
  979.         if (byte != 0x02)                /* verify that WEL bit is set */  A3 m7 q6 a$ a, r: k& L, A9 s' d
  980.         {
    + C8 {  F: x1 ^) L- N/ \
  981.                 while(1)3 C7 Z7 A) f$ D7 H/ k  f
  982.                         /* add source code or statements for this file */5 d; \8 D$ ]1 ?7 n
  983.                         /* to compile                                  */
    ! ]( Y& K- N; Q  g' u+ t
  984.                         /* i.e. option: insert a display to view error on LED? */
    9 n9 T* w5 |1 D7 _& l, [- A
  985.                  8 Z( R! U; F7 f, w% O% Z
  986.         }
    . o  F( \- S& }) L8 c
  987. }
    2 k; r# P8 e( l

  988. * _0 W3 @; |: @$ c4 g# V$ J
  989. /************************************************************************/4 y0 h& r# U5 S9 Q% D4 k" @+ I
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */7 a2 i; e" g; h/ @# F. y( ?2 ~4 J
  991. /*                                                                                                                                                *// V1 u% [. U  e5 S% f' Y
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    2 g& l0 r8 o9 ?  c5 E7 F) e. i1 y
  993. /*                                                                                                                                                */! w( _4 N( M1 \7 K- i; i' h; v
  994. /* Input:                                                                                                                                */
    % X1 l1 ]6 a6 v  t! T& {
  995. /*                None                                                                                                                        */4 g/ G" P! ^6 [" Q, F
  996. /*                                                                                                                                                */
    4 Y# n( H6 [1 K) a% V% Q( @+ o0 t% Q
  997. /* Returns:                                                                                                                                */( d& w, ~* }/ u0 V( R" ~
  998. /*                Nothing                                                                                                                        */, D1 o7 x( A# m; x; e, P! H2 t
  999. /************************************************************************/$ \  w5 S$ r% f
  1000. void WREN_AAI_Check()
    6 p% q6 s* O8 R8 h' |! J; B' Z
  1001. {
      G: }. a0 f& z9 a6 ?. z1 ?* R
  1002.         unsigned char byte;6 g* a2 _7 D: n+ D8 w5 f* c
  1003.         byte = Read_Status_Register();        /* read the status register *// W* l* e5 V: [1 g4 |, b
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */8 C5 C- S% \* c
  1005.         {1 L  |7 Q) N3 L9 b
  1006.                 while(1)                # l* L7 u# m- Q* r
  1007.                         /* add source code or statements for this file */4 W4 u2 W7 c- T3 `
  1008.                         /* to compile                                  */
    4 w2 _1 L1 @5 `
  1009.                         /* i.e. option: insert a display to view error on LED? */
    9 p; M7 c3 {7 D. K# r

  1010. % U. B# b3 r0 }( V
  1011.         }
    ) u7 v: i3 |) C% p( l. d% A2 g8 G
  1012. }
    , a- H4 @! S9 V0 l$ \" U2 \# G

  1013. % I2 |9 S- [0 i+ m3 ]" k# s  r
  1014. /************************************************************************/1 z. q$ B  W' b- P; ~6 _
  1015. /* PROCEDURE: Verify                                                                                                        */
    6 H: v5 [2 Q# z- j9 m* L" W
  1016. /*                                                                                                                                                */
    " T2 k( W+ e. D6 z: N% C* O! k0 J
  1017. /* This procedure checks to see if the correct byte has be read.                */
    4 y' g6 f6 d; U% v9 C$ x2 X: j
  1018. /*                                                                                                                                                */
    ( N/ g8 g) ^  Y7 G+ v8 x
  1019. /* Input:                                                                                                                                */+ r- N. M5 P1 C+ T4 g4 }
  1020. /*                byte:                byte read                                                                                        */
    ' e' Y$ r9 a8 J2 g* v
  1021. /*                cor_byte:        correct_byte that should be read                                        */3 W# ~2 k- O( v8 W7 j+ C
  1022. /*                                                                                                                                                *// p7 T: [# Z! E7 R) c
  1023. /* Returns:                                                                                                                                */, a& d0 d2 W0 \- @
  1024. /*                Nothing                                                                                                                        */
    * ]" u$ K0 X, u, U0 ]2 M
  1025. /************************************************************************/
    , G* |( R/ j: Q8 m8 E
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    - b& W, U6 p9 `7 E, D- O  R3 u' c
  1027. {8 g1 W( s5 K& T4 @2 @: o; E8 H
  1028.         if (byte != cor_byte)- p7 ?/ _' D) K1 |# g
  1029.         {* L0 q2 ^* e/ ?$ a( X4 c- w' n% t
  1030.                 while(1)
    , v6 _# P, R) r) V# _$ U4 q
  1031.                         /* add source code or statement for this file */
    1 c5 n: t. d5 I' f
  1032.                         /* to compile                                  */
    " o0 ?$ t  r6 Z2 s* x
  1033.                         /* i.e. option: insert a display to view error on LED? */" Z+ Q6 ?+ B! a( N; y1 r) P' x
  1034.                
    - B3 ], ?  d1 {! D- S1 L
  1035.         }
    ; v6 g1 O( v" s; r7 M  m1 U& s
  1036. }4 }% S& ^( O1 {0 r% W
  1037.   C9 e& ~- a2 z% T" ^

  1038. ' ~8 e0 Q" N' B8 E0 o1 P
  1039. int main()
    0 z2 P" H1 w% K4 C
  1040. {# c2 I8 a! V: M' e" u% f5 k
  1041. ) I, m- Z* U# L4 z
  1042. return 0;
    ; V* ^; r' g$ B2 c8 E" N$ M
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:/ y  U/ d. B" C1 I  _
   main()) t/ N; Q6 b: C% ?4 M0 E
   里面怎么是空的呢?  Y9 H7 O+ Y2 ~4 e
   发一份给我吧8 N2 c4 b. D) ]) M
mail:luyijun2005@hotmail.com1 O, W# f$ v. E2 Y
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。/ j) h# V. k9 I) T" G/ W7 Y

- q! q3 }- l+ O3 h7 D. X[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
0 m, a  ^8 f9 W: y  qEC的代码在哪跑,你看DS的说明,每个EC都不同的。
. C- G- v9 T7 y' D5 dOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
( A* J7 {1 z6 r6 \上面几个问题是你没看任何东西而白问。
! M8 R' |* K2 `. z! b% X8 }) ?( H( F( Q0 E& b
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

: t% J( t( y" g6 G关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
5 o2 g2 L& y3 Q
5 U, `/ H7 P3 a# `关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”% o  j" ]5 |$ _9 F2 |( |
" a; Y. S$ @- r0 |- P+ u
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...4 u. j4 Q2 g3 ?& Q
: Z3 A1 Y' q& ^
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样" k, h/ r6 L# Z7 I. ~. c! z
似乎要把SPI能support 到最大,这EC chip应该有好卖点0 {- @* r- p, ?& Z1 u* t
BIOS功能要不要强大,也就决定了SPI Flach的大小
) ]( V: G# E( C2 l& }+ I我是这么想的~让OEM去决定要挂多大!! D$ q. T. E' `: M, l% k* v9 M
如果我司有BIOS工程师就好了~哈7 d* Q9 J4 `  p
WPCE775应该算很新的东西,来看它支持到多大?
" c. j' g3 X2 [2 A* D+ [# k! T; n! `/ `' e  b$ Z. U, q; N
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
/ W( l! O2 V. Z其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.' P* x0 k  ^) S: D( j- c/ q

. N2 r. [; x# U+ Z% Z4 f这份driver收下~希望以后有用到2 w" c  t2 X* c" Z7 l6 o- p
谢谢bini大大( s. m) |" T/ t, S+ B% i: D2 ~4 {$ _

5 B9 j4 t+ y: k4 T, j; {9 Z1 y很新很新的新手,如有错误请指正 (准备看第二家的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()
/ C3 ~4 w' k  z7 e8 \* t' q  y" S3 ?{
1 N3 W' C9 D6 u3 m7 k% x2 f        unsigned char temp = 0;
1 {7 H) k) p5 n! @        CE_Low();
/ f; ~2 Y+ w' u$ _4 x    while (temp == 0x00)        /* waste time until not busy */
* p! y' b- Y, F+ W4 X3 C                temp = SO;
  u' z/ D0 Y& z6 a: v        CE_High();
& ], s$ b5 ]$ o9 c$ _}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
5 [. {/ D" K  K  a# A0 n# u4 a+ a{
0 w, x  \. a# m; J$ f        % @% ^: c: v" a! v: N4 S( p/ m5 E
        unsigned char i = 0;
0 e- Z$ f+ e9 }        for (i = 0; i < 8; i++)" F! O1 o4 G" {1 b; H3 L
        {
8 @  }1 f) V3 L2 G1 Q, j' k0 s* \               
. b0 `5 c5 b% I: y# x                if ((out & 0x80) == 0x80)        /* check if MSB is high */
( P  u- j; G7 z5 D, W                        SI = 1;& Y+ H& W+ K' @& I8 L
                else3 g" }0 F  i" J
                        SI = 0;                                /* if not, set to low */( {/ t& G% M- p( q9 `
问              SCK = 1;                                /* toggle clock high */0 j  ]6 B0 E$ U) M! O4 ~2 X
   题            out = (out << 1);                /* shift 1 place for next bit */6 T/ h, E6 i: i. W! w
                SCK = 0;                                /* toggle clock low */: Q2 Z& N+ ]# a. f/ V% d2 d* J
        }0 w+ q7 m6 {* h8 S5 q6 U
}7 [- z) \$ Y5 j% k
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-2-1 04:16 , Processed in 0.064603 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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