找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54324|回复: 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
    / w3 V* E3 N1 x/ R
  2. : F* t1 ]3 S( Y: [! F2 I6 r
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    - @9 s4 n. a8 b  B+ s$ v

  4. . K/ w$ X+ _8 `) S
  5. November 4th, 2005, Rev. 1.03 \& @: Y) e- k! P. F

  6. 1 [5 E7 O  B# T% k
  7. ABOUT THE SOFTWARE
    9 }, u4 a3 c1 t. T2 z
  8. This application note provides software driver examples for SST25VF080B,9 l  h* a4 w" J5 P
  9. Serial Flash. Extensive comments are included in each routine to describe
    $ I6 U. o9 J: e7 x9 ~5 p$ H
  10. the function of each routine.  The interface coding uses polling method ! s5 Q, U( R: J; b! [
  11. rather than the SPI protocol to interface with these serial devices.  The
    8 v: W! n' [- h* F4 x( V& L
  12. functions are differentiated below in terms of the communication protocols7 D$ q2 B0 z& @6 Z5 t* ]
  13. (uses Mode 0) and specific device operation instructions. This code has been
    ( m0 R- D" x+ m7 x+ R
  14. designed to compile using the Keil compiler.
    - z( r& s9 k# S; K/ d& s( |9 Q

  15. 2 T* s6 W, \* C6 l/ y

  16. ' E% y- y  W4 l
  17. ABOUT THE SST25VF080B2 S# e$ L. k; b% p" N' {) Q
  18. ; ^/ @9 s) A2 r+ U& E( {
  19. Companion product datasheets for the SST25VF080B should be reviewed in 2 g6 J3 m) a* e* |# w$ ?
  20. conjunction with this application note for a complete understanding
    8 m% A* X. [' o
  21. of the device.
    7 c4 S9 t8 |, V1 E9 F$ v

  22. % d% o, W2 V5 H/ C! s
  23. ! n6 j# ]  Z1 r, t- ]
  24. Device Communication Protocol(pinout related) functions:+ c7 i$ B! d8 O+ q- Q8 e! j
  25. : k6 S, p3 g2 n0 t* M. S! T% P
  26. Functions                                    Function. O& Q7 L( N4 G! a+ z
  27. ------------------------------------------------------------------( x$ x- N$ F1 J' S* X
  28. init                                        Initializes clock to set up mode 0." A+ {% V, ]& B) ?' W3 g* ^
  29. Send_Byte                                Sends one byte using SI pin to send and 6 e- r! Q& R( m! a/ P* ^3 i
  30.                                                 shift out 1-bit per clock rising edge
    0 [3 [. i/ n, ^8 O" ~" V
  31. Get_Byte                                Receives one byte using SO pin to receive and shift % V& H$ M3 G5 T. l
  32.                                                 in 1-bit per clock falling edge+ M, L7 Q2 I9 `: n( A* ]
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming2 H, {! x' f5 X# ^, k: f* l3 n
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high  _+ `5 Y) ^$ Z
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    5 V9 @+ Z' A3 J( W' N0 ~+ b2 _7 U
  36. Hold_Low                                Clears Hold pin to make serial flash hold, P" P  P0 z8 `7 r% T4 w9 M
  37. Unhold                                        Unholds the serial flash9 I5 k6 P1 i0 i# T0 Z. Q4 Y
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    ! ~0 H3 S' H4 w% m. f: a# e
  39. UnWP                                        Disables write protection pin; ]: a) l/ i6 G2 A  k
  40. . w5 d) `) W# p
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    " D4 |1 n2 g' K
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    & w2 z( X6 B# D" u6 A' k( X
  43. software which should reflect your hardware interfaced.          
    7 ?  R$ [* f) G& N

  44. 1 P( q4 c9 @; n" ~( {* s7 T' t

  45. / H0 p& P5 B& J
  46. Device Operation Instruction functions:
    # ^5 d2 V; q" s

  47. + N$ \( p2 R% D( M$ A/ ]
  48. Functions                                    Function# D. h& `, i, z
  49. ------------------------------------------------------------------
    4 w2 ^% Q( E. r1 u% L' D
  50. Read_Status_Register        Reads the status register of the serial flash
    0 J9 O, O  c/ T0 O7 }) t: }
  51. EWSR                                        Enables the Write Status Register
    : h4 U0 y3 S8 t$ H
  52. WRSR                                        Performs a write to the status register$ @3 g5 Z3 c8 a: Y+ o1 Q) e
  53. WREN                                        Write enables the serial flash' s9 z& a6 O  C( Q/ M# }3 I$ e8 P
  54. WRDI                                        Write disables the serial flash
    2 \$ O4 N5 n, X( ]+ V
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming2 B6 T" ?; y/ r  R) _
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    3 b: a, U9 t1 Z) }
  57. Read_ID                                        Reads the manufacturer ID and device ID8 r+ q/ F/ `" B0 J3 G
  58. Jedec_ID_Read                        Reads the Jedec ID
    & W' `1 w# s6 P' Y& ^
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)1 E# U* ^" @' h$ g, l
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    6 r9 W' a1 ^' V" ~1 d$ r7 ~; w
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)+ X. O" M) G% {
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)/ I2 b  i+ y) y" f+ {" b
  63. Byte_Program                        Program one byte to the serial flash
    2 q7 |% y$ V! ~1 C
  64. Auto_Add_IncA                        Initial Auto Address Increment process
      ?6 Y, W6 F  W8 j& w! j% @
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    9 K2 r) z6 q' c$ `8 H6 ]  W
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY" K* W0 a: `9 Y# E- f( @4 y
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    , }- A! \0 g' a# p
  68. Chip_Erase                                Erases entire serial flash1 f- V' j% a! _$ N/ O+ m- V) |/ C
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash& |7 P4 o8 D  b+ v- m
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash% l& M7 s" c0 Y: O* I; _$ r
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    9 q3 F" @7 g" X7 v+ v4 y
  72. Wait_Busy                                Polls status register until busy bit is low+ a! G( g" l7 F* M% X% `
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    / F" ^7 H0 b  p4 |. E& y4 Z; V
  74. WREN_Check                                Checks to see if WEL is set
    ' U/ q9 d" M! W8 N! |  N* z6 @. D
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set$ c4 e" i" K+ y# s: M! F
  76. ( p$ Y) c. e% ]& m  J! M

  77. 8 ~) C' I* Y2 u3 ^

  78. 4 k7 j7 ]& O; e% b9 {! c# k
  79.                                                                      2 t# ]( G: v/ ^3 P5 T1 V4 \3 S* F% ?
  80. "C" LANGUAGE DRIVERS 1 R8 E+ w9 `: N1 H- }, \2 @

  81. " H' l; S0 r/ F  e. ]/ ?* [+ Q- @1 a* t
  82. /********************************************************************/
    : Y; n; T2 R# x) x
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */- n: E* j2 [; z% z! _, X
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    4 o/ o" x6 n& X4 ]& C* h
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */7 _& I( Z+ e/ b2 y
  86. /*                                                                  */
    - C; G4 N) X2 c$ i1 ~" a
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    / O/ A4 S2 `7 A$ c
  88. /*                                                                  */
    + r6 ?/ a- K3 m$ a; C
  89. /*                                                                                                                                        */0 ?% Z1 B8 K& Q2 d4 h6 i
  90. /********************************************************************/
    5 k* i# o* _" o/ ^$ s5 c- n8 A7 D

  91. 2 B8 W3 {# X2 r, D$ D" q- O: W. z
  92. #include <stdio.h>
    * `' e1 t. \) Z# P6 ~* _$ _  M
  93. #include <stdlib.h>
    , h0 b4 b' N, A6 \" I4 h) m1 }. P- d
  94. ( D5 i% U: I0 @, P* C
  95. /* Function Prototypes */
    * w$ }; d1 M- n1 f- ?
  96. % x/ A9 V+ z" b, y
  97. void init();
    * b& ^% U+ L0 i
  98. void Send_Byte(unsigned char out);3 _" [  ~. F3 i& ^! x
  99. unsigned char Get_Byte();
    ! S$ t4 U7 S) W; X
  100. void Poll_SO();
    4 k% w5 E. x  a. T$ k% G9 e# ?# C- y
  101. void CE_High();
    . n8 f# j! ?+ @9 T& f: j) K
  102. void CE_Low();
    0 I% l( _$ r) z9 N1 p
  103. void Hold_Low();
    ; n, K* ~" [1 u' E& ?5 `
  104. void Unhold();
    5 y3 t8 [  Y& d; P1 }2 m
  105. void WP_Low();
    " ~: a* I; m, S& x, Y
  106. void UnWP();
    0 I2 ]8 {5 W6 a5 Y9 o) y
  107. unsigned char Read_Status_Register();
    + h5 S5 u+ k+ W$ ^) O$ S% W$ [
  108. void EWSR();0 n( u; ^) v7 @& l% F( [% h' x
  109. void WRSR(byte);
    ( K! W2 ~* q; \
  110. void WREN();
    ! ?5 }6 E3 W7 U; k0 z
  111. void WRDI();
    ) e. n$ E9 j) b+ U- h+ z7 V$ K
  112. void EBSY();
    7 S+ [0 ~' m- P; b
  113. void DBSY();7 p8 R  z0 u8 Z! G/ b& y( l
  114. unsigned char Read_ID(ID_addr);* D1 c1 Z/ @' J$ Y+ S
  115. unsigned long Jedec_ID_Read();
    1 i$ U( e" f1 E. e8 g# h
  116. unsigned char Read(unsigned long Dst);
    ) D  @$ C* ^+ ?& h2 s
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);+ V" C0 q+ U  {. z, q7 v& r3 g& a0 Z
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    8 I1 t2 u  @5 B2 {1 t8 }( y
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);! g4 u0 |+ H( F+ a, Y, u  E' h
  120. void Byte_Program(unsigned long Dst, unsigned char byte);: ]5 a( R+ u! g' E
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);3 ^+ B4 [9 n: a8 b
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    + G3 R3 _6 w4 h; c9 j2 z# h
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);; I' Q) `3 F9 J5 G* @8 @
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);. m' b6 h( X' J0 b/ y7 N, }
  125. void Chip_Erase();
    4 J! J; b: u' n8 K8 p1 A/ b
  126. void Sector_Erase(unsigned long Dst);
    " x- b/ b+ K! R6 e  h
  127. void Block_Erase_32K(unsigned long Dst);3 `+ l; }! x( l# @! K
  128. void Block_Erase_64K(unsigned long Dst);
    1 ?% g) E: d9 }. L9 A3 _5 a( u1 j
  129. void Wait_Busy();+ u0 R0 a/ w1 O" b: ^
  130. void Wait_Busy_AAI();
    9 b. Y& v$ @; M  K
  131. void WREN_Check();
    . o$ D; K  D0 D" ^* n
  132. void WREN_AAI_Check();
    , r7 z1 ~% f8 O( a# `4 F

  133. 9 j7 e5 P3 p9 A+ a
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    & V$ F) `  \4 d6 v( y0 F$ \2 T8 g
  135. % Q* |+ Z/ f' g: q3 _
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    , R( q( k: |- C- b5 l8 m# t+ O3 ?1 |
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    2 i. @% J5 d$ Y

  138. * n% N# K1 h; w) h
  139. /************************************************************************/6 c6 [4 F( Y8 j; l" b3 Q
  140. /* PROCEDURE: init                                                                                                                *// }; J, A9 ^$ C6 g, Y; k' e* ?
  141. /*                                                                                                                                                */2 N8 H( V, |1 x6 D9 T9 M+ ~/ ?
  142. /* This procedure initializes the SCK to low. Must be called prior to         */9 X9 y' z; i0 B
  143. /* setting up mode 0.                                                                                                        */" l% H( K6 x! o, H) G  {, w
  144. /*                                                                                                                                                */, ?/ J$ U9 @0 X  W" v
  145. /* Input:                                                                                                                                */
      H) ?6 h. L) p5 ]# E
  146. /*                None                                                                                                                        */9 |9 k% K* Q/ I6 k, [5 u9 @
  147. /*                                                                                                                                                */# _% @; `) @9 `6 W
  148. /* Output:                                                                                                                                */6 j  R- X/ \6 {( q7 ?
  149. /*                SCK                                                                                                                                */' e& d6 V! i) v
  150. /************************************************************************/
    ! S6 o2 P: k! v3 p+ H
  151. void init()5 H& O. b: ]8 i+ n/ }% P: l
  152. {  B4 z1 T" \5 u% W" a
  153.         SCK = 0;        /* set clock to low initial state */. s. y+ I6 A7 ]5 e" {' [$ a
  154. }
    . h; |9 _4 W" [8 v/ [6 ]

  155. 2 Q/ p: ]8 r% R: a  y: c/ D! m
  156. /************************************************************************/& V  m9 x/ M- w# u8 K& b+ b
  157. /* PROCEDURE: Send_Byte                                                                                                        */$ g) f5 e0 h! Q; M7 \$ O
  158. /*                                                                                                                                                */
    0 @  w7 H% z9 p, {2 k
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    5 m# I2 Z6 j* X; M* `3 B* u( l
  160. /* edge on the the SI pin(LSB 1st).                                                                                */8 R/ V) f+ P" ^
  161. /*                                                                                                                                                */
    9 x0 i7 U( @/ D3 U+ u; u
  162. /* Input:                                                                                                                                */
    / t" t2 ?" }; h. ^
  163. /*                out                                                                                                                                */
    $ Z7 r. b2 ^5 e
  164. /*                                                                                                                                                */6 B# R3 a6 t3 y, ^1 P
  165. /* Output:                                                                                                                                */* Q9 {4 b8 V: |3 w1 M9 J& j7 f
  166. /*                SI                                                                                                                                */3 h* y; g) ]* a) m
  167. /************************************************************************/  q  Y8 ?4 |( X( C- c2 Z
  168. void Send_Byte(unsigned char out)% P1 F' Y& V2 H0 w- _# u
  169. {& m- g3 F6 s- l8 _% K
  170.        
    5 X" h4 \: s( O/ o4 Q8 p4 w0 T6 V- E
  171.         unsigned char i = 0;$ b2 D3 S+ z0 |- x  O" m
  172.         for (i = 0; i < 8; i++)& a/ L- k- u% ]0 n& b6 x" Y5 P' V
  173.         {
    7 l6 D3 }. m$ r! z- g: a; `7 C
  174.                
    , c/ {/ p) ?# M% f" `- n/ {
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    $ ^3 D$ I2 a( w4 C
  176.                         SI = 1;" y% n3 C1 E. ~6 z
  177.                 else: c/ _) t" g+ B+ m
  178.                         SI = 0;                                /* if not, set to low */3 G5 X" K, p* K) J0 `" Q
  179.                 SCK = 1;                                /* toggle clock high */9 t+ H- w* U6 C4 a9 N
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    1 K2 @) B) X- e( Z1 _& o* [
  181.                 SCK = 0;                                /* toggle clock low */# o' C, F4 f3 q) Z
  182.         }
    : ?: q: m' P; ]" M% G1 b( y
  183. }0 \: _* }- a' f5 Z

  184. , J7 ]5 w( D7 J
  185. /************************************************************************// ^6 l* v; Z/ \1 @/ n+ f1 c  c4 o
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    & l" w- ?9 ~: r8 ?$ e
  187. /*                                                                                                                                                */; Q. N' ?) M5 C8 j& i% B0 e
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */1 h  p3 d- N% A3 O) l
  189. /* edge on the SO pin(LSB 1st).                                                                                        */* t7 z2 l5 T7 V) r' [. B  J2 p
  190. /*                                                                                                                                                */
    5 }, s8 `2 q( H. Q: f1 g3 x, }
  191. /* Input:                                                                                                                                */* b+ A; H! J% s- b4 B
  192. /*                SO                                                                                                                                */4 R5 p3 V+ f. \
  193. /*                                                                                                                                                */
    ' s$ X; ]0 y6 j' ^. Q$ {
  194. /* Output:                                                                                                                                */7 r: E9 R$ h5 p
  195. /*                None                                                                                                                        */+ n" \/ Z8 V; T" [% z
  196. /************************************************************************/
    ! B$ @6 h: O+ o- k
  197. unsigned char Get_Byte(). Y! S  \- E/ N1 L1 _5 O
  198. {
    4 @& E7 f, x8 L6 A9 ^/ n
  199.         unsigned char i = 0, in = 0, temp = 0;
    6 M1 B8 o' B# T, \5 t
  200.         for (i = 0; i < 8; i++)6 P: G/ Q8 K! c; V; i" q
  201.         {
    1 ?" w& o' ?+ V8 a
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */% {, S. J: S( }" [" q
  203.                 temp = SO;                        /* save input */; F5 r" b) H9 s* {# f  \, d0 w* m
  204.                 SCK = 1;                        /* toggle clock high */
    . J; `7 ?5 |( B% k* z9 R+ }6 g
  205.                 if (temp == 1)                        /* check to see if bit is high */0 _$ n& a; x3 i7 t
  206.                         in = in | 0x01;                /* if high, make bit high */
    % O- v* w( t! h! Y7 G; z2 c
  207. # S5 y, E. X7 |6 |! s. A
  208.                 SCK = 0;                        /* toggle clock low */
      X1 ^1 ^1 p" x

  209. ; B1 v0 y' [' e. h8 ~
  210.         }8 j! M* C, v. y# z- m% U
  211.         return in;; a& J4 v+ h) T% G1 _( Z! D
  212. }6 c2 H, @0 v+ f) U. {! d5 k
  213. 2 L7 d* J# f: a% g" O6 T* P
  214. /************************************************************************/
    5 ?) O* L! e# i. |& e; ]7 a
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    0 I! d0 D$ g1 w( T# W  ?2 J# j
  216. /*                                                                                                                                                */% i9 C0 \5 l: w  G( M# b, b
  217. /* This procedure polls for the SO line during AAI programming                  */- P$ G  ?8 k2 O
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    - ?2 ?- R% g/ c) D5 ?0 B6 e) w
  219. /* is completed                                                                                                                        */
    , s! }! E; B3 q5 r/ |0 ^9 ~
  220. /*                                                                                                                                                */7 p! |+ @# @) D4 ~/ m8 O
  221. /* Input:                                                                                                                                */& v- i* ^% s7 C+ X
  222. /*                SO                                                                                                                                */
    ( e- e4 {3 M  a2 F* }0 i' v
  223. /*                                                                                                                                                */
    # w8 V  {, x' Y$ v  L
  224. /* Output:                                                                                                                                */
    3 C& B) r( X6 F8 A5 C: }; w
  225. /*                None                                                                                                                        */
    $ |7 J& f2 m+ O8 E( A, X
  226. /************************************************************************/2 Z; h9 z8 c- D: `2 a
  227. void Poll_SO(): u) V. n9 M) k- I
  228. {
    , O* N4 C7 G. {7 A# Q
  229.         unsigned char temp = 0;
    & }; O+ v1 T1 M/ ?; J3 ]) e* |5 ]! l
  230.         CE_Low();& [8 E4 m% h  y5 s$ \  U
  231.     while (temp == 0x00)        /* waste time until not busy */- T& H  E4 f& r4 C
  232.                 temp = SO;4 p* n; C0 {# @, V. y3 k
  233.         CE_High();
    0 s  D8 p( U7 j5 F- r
  234. }5 u7 ^) J* o$ T& S

  235. 4 c% m% W. M% L  u' w' w5 |
  236. /************************************************************************/& @! [& y  _6 [3 z* m( Q) a; \
  237. /* PROCEDURE: CE_High                                                                                                        */3 D; C! j& C2 b6 G& A" t. g
  238. /*                                                                                                                                                */
    9 R1 S7 G' ?  I* F. F2 N( V
  239. /* This procedure set CE = High.                                                                                */. ]. l2 b  F0 Y* @! q
  240. /*                                                                                                                                                */- c  ?+ z6 _) J) `* B) ~
  241. /* Input:                                                                                                                                */
    - x3 B/ c/ g1 j: ^& u
  242. /*                None                                                                                                                        */
    ; \# p% U& x3 L2 z: |9 q
  243. /*                                                                                                                                                */
    5 s2 f+ K7 Q% }5 ^4 o( [2 e
  244. /* Output:                                                                                                                                */) f) K! X+ Y) B, O
  245. /*                CE                                                                                                                                */
    : d4 ^3 H9 R1 i0 m
  246. /*                                                                                                                                                */- g6 E9 y$ }, l
  247. /************************************************************************/
    ( r6 a. o. \4 D
  248. void CE_High()
    + A4 r5 P9 r3 j7 \6 {, E
  249. {
    # ?; n' ^, _  N! Y) o9 T
  250.         CE = 1;                                /* set CE high */
    3 {; ~& Q! [6 g9 g. T3 F7 ^
  251. }
    : K& ~4 Z7 l' C

  252. 8 e( @; ^' `( g' b% z( P
  253. /************************************************************************/
    + v7 }! V$ Q  \& d* ?4 S7 K$ v2 N
  254. /* PROCEDURE: CE_Low                                                                                                        */0 [3 g, Q* S+ e
  255. /*                                                                                                                                                */
    ! E; u# F8 f2 `
  256. /* This procedure drives the CE of the device to low.                                          */& v* U8 W+ k5 g
  257. /*                                                                                                                                                */
    . @1 M4 {; ]6 P; g2 ^$ k
  258. /* Input:                                                                                                                                */
    ' d8 H6 d' w2 {" q
  259. /*                None                                                                                                                        */
    2 M$ H' i4 L/ I9 k
  260. /*                                                                                                                                                */9 K* G  X3 O  C' e% b! i' L( Y
  261. /* Output:                                                                                                                                */6 o! E6 u. F5 |* R
  262. /*                CE                                                                                                                                */
    * `8 ^# s7 E/ d' w+ Z# A$ E9 w  {
  263. /*                                                                                                                                                */7 E3 P6 _  r2 r& f! X+ D
  264. /************************************************************************/
    8 u- r; c. ?6 F
  265. void CE_Low()
    9 l9 }" \7 Q8 h- C: c
  266. {        : L5 S( z# @; K9 R% M0 `6 d
  267.         CE = 0;                                /* clear CE low */
    # ?# U5 m5 z0 d; Q+ Q7 c9 B: i
  268. }
    6 d  L4 Z( U, h1 Q
  269. . @0 z, l( P* `, r% g' Q. j
  270. /************************************************************************/; w3 H% z5 l6 e
  271. /* PROCEDURE: Hold()                                                                                                        */
    $ H% H8 E, K5 e5 r) ^* Q! g, I
  272. /*                                                                                                                                                */
    ! X! T- R3 e8 \! }# f
  273. /* This procedure clears the Hold pin to low.                                                        */
    5 p9 A& j1 a5 j& b& l; _
  274. /*                                                                                                                                                */* T& x, Z, c& f0 X8 j5 b; H! b. b
  275. /* Input:                                                                                                                                */9 z) u( L6 S4 W
  276. /*                None                                                                                                                        */! J8 x; M3 E% d2 K  ?' D8 i) g/ z
  277. /*                                                                                                                                                */
    & \. [. m. A: U4 I
  278. /* Output:                                                                                                                                */1 F8 @* X7 U- M+ Y- H
  279. /*                Hold                                                                                                                        */- r. ^: E( E, _  g6 _" Z7 Y
  280. /************************************************************************/0 K1 ^; ~6 E6 |0 ?9 E" J$ ~
  281. void Hold_Low()
    / [7 y' G+ x* {: F3 a$ y
  282. {8 w  T' V) @5 [3 a9 w
  283.         Hold = 0;                        /* clear Hold pin */
    8 U7 e" n$ q0 x' n" o, a0 k6 N
  284. }
    & I6 M3 D3 A$ d7 T# w
  285. ' S3 X$ b% J" `% m: M6 @6 s
  286. /************************************************************************/+ @, w- Z# M+ f& r
  287. /* PROCEDURE: Unhold()                                                                                                        */. U1 n+ |3 P) R7 u: q! V
  288. /*                                                                                                                                                */) x" s9 z' _) n1 i' l5 K. q/ Q8 Z
  289. /* This procedure sets the Hold pin to high.                                                        */
    $ R9 ^1 p; |, y4 k4 I2 C
  290. /*                                                                                                                                                */
    # A; l0 P2 I7 {; P" s
  291. /* Input:                                                                                                                                */
    5 d( m2 X. {* ^( h1 M" B
  292. /*                None                                                                                                                        */
    ' m; V4 L* H* p
  293. /*                                                                                                                                                */! ?( E3 |1 b6 W. ?9 ~1 f$ g
  294. /* Output:                                                                                                                                */2 ~3 D  C3 J3 C: ~3 e- x! g
  295. /*                Hold                                                                                                                        */
    % Q3 R( }5 O& M) G8 B
  296. /************************************************************************/
    - M$ b) h# G6 @3 |# R
  297. void Unhold()4 G1 P9 U/ _) b# L
  298. {( K$ C+ C3 ^7 f7 T% z! F" w8 _
  299.         Hold = 1;                        /* set Hold pin */8 N; |8 n/ h9 N# `3 _! W
  300. }0 Z; Y9 X7 I+ m2 k% ]! A

  301. " y! O5 N# K: k) V
  302. /************************************************************************/, v! [# b( t# {, n$ Y
  303. /* PROCEDURE: WP()                                                                                                                */
    - J) |9 Y& V% Q$ d2 A
  304. /*                                                                                                                                                */) }: x6 w" b' M+ K- B
  305. /* This procedure clears the WP pin to low.                                                                */
    ; p9 C- M1 K2 k% A
  306. /*                                                                                                                                                */% `) [7 F. z: ?! R  t2 \( @
  307. /* Input:                                                                                                                                */$ W- c% Y* o1 {; r) ^5 z9 }
  308. /*                None                                                                                                                        */8 }& [+ K, M3 i
  309. /*                                                                                                                                                */
    9 O7 t0 d( n3 k6 r( Z2 G; P) r
  310. /* Output:                                                                                                                                */
    2 m. X! i0 K2 A6 O4 u0 {
  311. /*                WP                                                                                                                                */( ?$ Y8 r% [$ e2 T+ @
  312. /************************************************************************/; U2 `9 {( O/ ]- j! W, S
  313. void WP_Low()
    2 C' J0 x  b* h3 ?
  314. {2 P: g( n, c3 G9 r: Q+ j+ b
  315.         WP = 0;                                /* clear WP pin */. S4 E' [& k, B
  316. }# }6 K9 a' X! x) f- D

  317. 6 j( E2 \  r; N5 x: P4 F% M1 \
  318. /************************************************************************/4 S  `# e  V9 ?; w% _2 p9 I: l: U' ^
  319. /* PROCEDURE: UnWP()                                                                                                        */8 s  ^) R, Y/ H- W
  320. /*                                                                                                                                                */: [- ^+ P& r2 [
  321. /* This procedure sets the WP pin to high.                                                                */2 {% o9 G3 j) L9 w  l. C& O( ^
  322. /*                                                                                                                                                */  B& X, o9 C" a( c9 |; J
  323. /* Input:                                                                                                                                */
    ( |3 _' A* Y: ^
  324. /*                None                                                                                                                        */
      r0 V; `. L3 p& P- n: c! M. h7 V/ e
  325. /*                                                                                                                                                */! o7 _& ?* [0 E
  326. /* Output:                                                                                                                                */. c) k9 G' Q$ w) L3 N
  327. /*                WP                                                                                                                                */# l7 |% N% q* A) \; a: c+ g) ^6 e
  328. /************************************************************************/
    $ ]/ o4 l; ?6 e; K) w- J% ]
  329. void UnWP()% J4 E  R0 `3 c4 w# i1 `
  330. {& p' _1 Z' y- V  f+ k
  331.         WP = 1;                                /* set WP pin */
    * }0 Q8 o7 `# [+ J  _. K
  332. }
    : w" {3 }/ g8 A0 J! M* @$ ]! P
  333. 9 J7 f; d' A1 P- I; i
  334. /************************************************************************/
    6 L9 n1 v4 M, m; q- W
  335. /* PROCEDURE: Read_Status_Register                                                                                *// H. o; [. O7 H! j3 V1 H
  336. /*                                                                                                                                                */! o; F- o6 b- N7 d( b
  337. /* This procedure read the status register and returns the byte.                */# o2 ?% j2 p. O. Q$ X0 A6 j
  338. /*                                                                                                                                                */
    $ O% p$ J' e/ T& `& x; \
  339. /* Input:                                                                                                                                */
    * Y5 ~, Z7 [: k
  340. /*                None                                                                                                                        */2 W. }8 D4 `' a
  341. /*                                                                                                                                                */
    ' n( o8 j1 I- Y4 j/ }
  342. /* Returns:                                                                                                                                */2 o( Q- q& G3 ~1 h* @) r" A
  343. /*                byte                                                                                                                        */) w. {: v  h+ ]+ o! @" b- L- W+ ]
  344. /************************************************************************/1 i5 z6 M& A3 v6 m+ H; Q
  345. unsigned char Read_Status_Register()- O  Y1 C3 j8 Z1 j" L& G* Q
  346. {
    6 |( |; F1 R% w4 \; K* b
  347.         unsigned char byte = 0;
    " {  F7 u5 |/ W* s- @
  348.         CE_Low();                                /* enable device */* Q2 v8 }7 p. X$ T$ J% N, @
  349.         Send_Byte(0x05);                /* send RDSR command */
    1 B# S& W5 z# ?( ?6 t
  350.         byte = Get_Byte();                /* receive byte */
    - S7 f3 C3 X0 _6 p, q
  351.         CE_High();                                /* disable device */7 n- z" X5 J1 o; O/ z2 }
  352.         return byte;
    / C; N2 ~$ V' D  Y; y: l
  353. }
    # X) f5 ?: W/ r5 N4 f( E/ ]
  354.   l( {( W2 P, I" G
  355. /************************************************************************/3 T! v9 C% d. b" [: ]1 B
  356. /* PROCEDURE: EWSR                                                                                                                */. M. ^# W* o$ c  r( w0 U
  357. /*                                                                                                                                                */' e% a0 Z8 B& W6 z
  358. /* This procedure Enables Write Status Register.                                                  */
    # q3 Y1 Y. Q& |: o7 [
  359. /*                                                                                                                                                */; F  l8 F9 a, l% J. j3 E
  360. /* Input:                                                                                                                                */
    # _2 `2 y- h8 T/ g) U% M9 }
  361. /*                None                                                                                                                        */4 b  B, b0 c* D4 N
  362. /*                                                                                                                                                */
    8 w1 s8 {9 m  ~( ^8 G
  363. /* Returns:                                                                                                                                */5 _3 d, K1 |6 _* p2 K1 `; ?. \
  364. /*                Nothing                                                                                                                        */
    7 s3 q3 S" ]; Z1 ]5 y! ]# s
  365. /************************************************************************/
    1 @) c* \1 D2 M2 a
  366. void EWSR()% m8 A- W! }2 {* {# R- M  T' M0 x
  367. {8 F! w2 P. b: z
  368.         CE_Low();                                /* enable device */" V: o  @4 X4 u
  369.         Send_Byte(0x50);                /* enable writing to the status register */( X- V2 Z& ]) G5 D4 X1 `
  370.         CE_High();                                /* disable device */
    4 u* i* m  t% V
  371. }
    6 K  t& Z2 Z. u7 \

  372. + V, `9 B+ Z' l
  373. /************************************************************************/
    2 g, I; S/ e( o
  374. /* PROCEDURE: WRSR                                                                                                                */
    + y5 c! _4 s9 u2 i8 U
  375. /*                                                                                                                                                */6 u; q" h# Y1 ]
  376. /* This procedure writes a byte to the Status Register.                                        */& A7 @* d$ m5 s$ C
  377. /*                                                                                                                                                */5 k3 w& I. [. B, a
  378. /* Input:                                                                                                                                */
    1 x# A  Z1 B+ T( `/ h
  379. /*                byte                                                                                                                        */
    " F/ U# S9 l! D6 z# p
  380. /*                                                                                                                                                */) M8 @/ `- g$ R) X
  381. /* Returns:                                                                                                                                */; @/ Z! b; ^9 f
  382. /*                Nothing                                                                                                                        */2 C( A) S! X" @3 L! h' N& j8 H  J
  383. /************************************************************************/* ~1 \+ c2 h6 T/ Z* X8 r9 F2 o
  384. void WRSR(byte)5 p# F! S8 B' L6 r& G* T! |
  385. {
    ; X. s2 `: ?$ R; H7 H, _% a& z' g
  386.         CE_Low();                                /* enable device */# F$ U: u/ ?8 Z
  387.         Send_Byte(0x01);                /* select write to status register */$ r% `9 b& m- F: [
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    8 p1 H: n8 R3 j& q  b
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */% U# _$ |! G1 m' _6 s% P/ l2 j
  390.         CE_High();                                /* disable the device */
    & b% o: C/ x: s& f9 R; R) O6 Y
  391. }3 G9 k4 s9 U2 N4 k* E8 A

  392. $ j( \# c6 D4 @3 r1 O0 `
  393. /************************************************************************/
    . h! |6 L- f8 ^) y* F! e
  394. /* PROCEDURE: WREN                                                                                                                */1 i2 v$ b7 @1 R7 \/ x
  395. /*                                                                                                                                                */  \9 \- h, m2 ^* d9 ^$ G
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    " W& }' X" S1 E7 o
  397. /* to Enables Write Status Register.                                                                        */
    $ w$ x- _. s# ^; D/ Q0 c$ B$ @% `6 r
  398. /*                                                                                                                                                */6 b4 i& F3 f7 C% {) w$ r
  399. /* Input:                                                                                                                                */
    4 s& P4 P0 h  r9 o+ C) e* G- h! L
  400. /*                None                                                                                                                        */3 l5 Y) T1 u9 O  m! h1 d
  401. /*                                                                                                                                                */( U, H. _0 y. L. Y. R
  402. /* Returns:                                                                                                                                */! J" c( Y: N7 l8 d0 m
  403. /*                Nothing                                                                                                                        */
    5 M1 ]7 i$ W8 l. c
  404. /************************************************************************/
    - E6 e% b" K& ~6 g$ s1 K# z
  405. void WREN()
    6 [# ^+ L6 y) l! i
  406. {
    0 }" c. l1 o$ M: f% q2 G
  407.         CE_Low();                                /* enable device */
    / n- M" L4 u" Y3 K" f: z' T
  408.         Send_Byte(0x06);                /* send WREN command */
    ' ^2 q. ^8 ]7 }" W5 ^7 r$ N& ]/ Q
  409.         CE_High();                                /* disable device */. Y, ^5 `: z3 G/ x6 ^& _
  410. }
    0 ?: T3 U& w. |/ r' |

  411. 3 j: Y  G3 m; {+ Q3 N
  412. /************************************************************************/
    ! G8 m, m6 m7 o, I7 M
  413. /* PROCEDURE: WRDI                                                                                                                */& Z% P7 ^( j  s# V9 L  G5 R
  414. /*                                                                                                                                                */
    / r+ |! s9 D* l6 d5 E- f
  415. /* This procedure disables the Write Enable Latch.                                                */7 q" \* e# J* Y8 H7 C/ p5 x
  416. /*                                                                                                                                                */
    6 @. b9 G- p7 h: c6 b' \7 _% l
  417. /* Input:                                                                                                                                *// {! {: @0 S  u5 r
  418. /*                None                                                                                                                        */
    9 u# Z$ q) F5 t6 @( ^
  419. /*                                                                                                                                                */. D( Z( G. Y! K+ c! c) C
  420. /* Returns:                                                                                                                                */# Y- X* S# }. n( u# `0 p) R
  421. /*                Nothing                                                                                                                        */
    7 S- A: I' V" E$ T, h* p; y
  422. /************************************************************************/
    6 U3 C* W8 p& v- H8 X) `3 f
  423. void WRDI()0 x7 V  }0 d2 }
  424. {, }  r# L. Y5 v3 w
  425.         CE_Low();                                /* enable device */
      ]) q) [& z" _# {1 I$ f9 s
  426.         Send_Byte(0x04);                /* send WRDI command */" {+ i2 d3 j* Z% s' w0 e8 }
  427.         CE_High();                                /* disable device */$ d( A7 X- a- |" Q& e5 {- W
  428. }! s% V* f5 W- S, p6 S0 _
  429. , J2 r- }' U; e2 u" M1 X
  430. /************************************************************************/
    3 q7 e( |# u  @: ?, I% @/ v
  431. /* PROCEDURE: EBSY                                                                                                                */
    0 _2 _7 ]% E# A  u- r
  432. /*                                                                                                                                                */
    9 Z3 Z5 M. p/ ]% Y8 G7 I
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */( R2 P+ H( Q$ H- s9 k
  434. /* programming.                                                                                                                        */6 g* [; I: [3 u$ c6 j, {
  435. /*                                                                                                                                                */
    + d4 n3 r, a. X' y& Y8 L
  436. /* Input:                                                                                                                                */& e+ b' u9 W3 ?& @$ S' T% j1 j0 M8 h4 ]
  437. /*                None                                                                                                                        */
    : \* S. t5 t4 O& L) H1 E: [9 ?
  438. /*                                                                                                                                                */
    ) ~! ]9 \% z! O2 q- L
  439. /* Returns:                                                                                                                                */+ s, \+ q* r2 S; I4 Z
  440. /*                Nothing                                                                                                                        */% R: p- r: `$ X( J# |' [) b
  441. /************************************************************************/
    : G6 @# K% A1 D* t# R
  442. void EBSY()# V% S; g& M" R. g& E: V- Z
  443. {
    7 N! L- O7 ?4 y1 L7 a; e# m0 c8 j
  444.         CE_Low();                                /* enable device */# e& P0 I/ A$ K! O* y
  445.         Send_Byte(0x70);                /* send EBSY command */9 R+ L7 d4 M3 p; k, Z- L0 n
  446.         CE_High();                                /* disable device */3 i1 l* R+ h7 ]
  447. }9 c4 v! K9 }1 l5 n7 {# k# k
  448. - T' Q) C4 c# {4 l5 o5 P
  449. /************************************************************************/
    # j3 _7 D- ^4 F$ O$ q9 K6 E7 a: {
  450. /* PROCEDURE: DBSY                                                                                                                */$ ~3 \* C7 [; {) E$ _9 h4 e: e
  451. /*                                                                                                                                                */6 l8 `# m2 E5 C4 J) @3 `4 r
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    " d+ @2 a6 y( k7 n
  453. /* programming.                                                                                                                        */
    7 {9 W' w3 f" @0 ^# Z0 x: b* X
  454. /*                                                                                                                                                */5 }9 ^( r2 X4 q# y: _# _& G7 N
  455. /* Input:                                                                                                                                */
    ( [2 M. R3 w' X$ }/ j2 x% J
  456. /*                None                                                                                                                        */
    # Y8 S* u8 _: v# x  K" ^9 |! J) q
  457. /*                                                                                                                                                */
    # j! R6 E4 s' F/ f, w' P+ e! _
  458. /* Returns:                                                                                                                                */
    $ Z9 F4 [# R" G( g9 u* r$ G) _5 H8 K
  459. /*                Nothing                                                                                                                        */2 v, V8 e. q. f8 @- l
  460. /************************************************************************/
    * X/ i6 p8 s9 @/ }1 i- w
  461. void DBSY()
    ' s2 z  b9 a7 L4 ~
  462. {
    , o+ e" i/ @  A' W/ A  d
  463.         CE_Low();                                /* enable device */
    . j) E' m2 L. W$ N
  464.         Send_Byte(0x80);                /* send DBSY command */
    ) i6 W; U0 {. D$ M! G
  465.         CE_High();                                /* disable device */
    . U- p8 m( ~! {  I- f! ^
  466. }
    9 w+ L* p/ ]$ n; d+ s( n# X

  467. 2 I% W8 `+ X$ p$ f3 m* V
  468. /************************************************************************/: }. C! h+ d9 t
  469. /* PROCEDURE: Read_ID                                                                                                        */4 j1 K+ n9 k+ C2 ]/ Q
  470. /*                                                                                                                                                */+ g+ p! S) |( _0 m/ V( E
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    ) l3 `3 j! i! [9 P# P. L
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    ( I* a4 F7 G2 q' a' l& `
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    , g+ Q) w! W5 q2 L" j2 I' i. G0 \
  474. /* whether the device outputs manufacturer's ID first, or device ID         */& P& I- d8 _- N8 q
  475. /* first.  Please see the product datasheet for details.  Returns ID in */$ ~2 I) N% K2 b8 A; {- h
  476. /* variable byte.                                                                                                                */
    " u, o. ~0 T2 _
  477. /*                                                                                                                                                */2 G# O0 G9 N* x& F. n
  478. /* Input:                                                                                                                                */
    / h% Q! [, n  f) q; v" u/ a
  479. /*                ID_addr                                                                                                                        */
    . J! J( `+ c5 {& @+ F: d( S" f5 u, \
  480. /*                                                                                                                                                */
    4 L  t+ z+ c* k
  481. /* Returns:                                                                                                                                */
    3 ^$ N: _! p! K# B$ U. z- k
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    & h5 h0 P" @# s7 D3 K  N8 H
  483. /*                                                                                                                                                */
    , U! ^* `  M+ P' J3 P2 m
  484. /************************************************************************/. g' _" H7 x5 |( J& q0 W4 q/ {1 ]
  485. unsigned char Read_ID(ID_addr)! N# z; I9 q" n: d, P
  486. {+ o5 ~* U" L) A  s( h' O  T8 b8 n& D
  487.         unsigned char byte;
    6 o, g6 B7 _: w+ l: t. T1 r# b/ m! F' \! a
  488.         CE_Low();                                /* enable device */1 D3 V8 d( G3 K- }
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    8 d" E4 Q$ m+ d- U+ n) z% q0 l
  490.     Send_Byte(0x00);                /* send address */
    . T% Q# Y5 y' a+ @4 U3 b  ~
  491.         Send_Byte(0x00);                /* send address */
    6 x1 @9 m( D$ r2 \% o$ w
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    " p, k- r9 V: p& o. P9 |
  493.         byte = Get_Byte();                /* receive byte */( `  T/ R1 a, w6 v3 J$ b/ B4 V% x. V; _
  494.         CE_High();                                /* disable device */
    9 r6 _" s6 @+ S3 d
  495.         return byte;
    & G5 R, K* d" Y) T' J0 q# d
  496. }  ^. b/ j8 ]- c* q
  497. ; |, W& m# y" |- ?; H
  498. /************************************************************************/; t9 h# i3 z/ \  G) u6 L
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    6 \0 z2 l. F# u1 }
  500. /*                                                                                                                                                */
    3 w' `$ L" E3 ?( Y' I( S
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */, x) [1 J5 Q. {; E4 q. J( \
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */+ R9 R- g8 [4 l9 o+ `
  503. /* Please see the product datasheet for details.                                                  */
    $ m- h, \  n0 s
  504. /*                                                                                                                                                */
    , M, M9 m7 j! m- ?
  505. /* Input:                                                                                                                                */% h% n" c* `3 _- K
  506. /*                None                                                                                                                        */7 t; G9 V  _+ S, O; E7 c5 n
  507. /*                                                                                                                                                */
    - B. r5 m. j+ r, M$ i
  508. /* Returns:                                                                                                                                */
    % `$ H$ e+ w% n. d+ P: a2 `
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    ! i8 P6 j- l% G1 x: A; R  S# b
  510. /*                 and Device ID (8Eh)                                                                                        */
    9 L9 f  @5 l( X0 U3 K! k
  511. /*                                                                                                                                                */3 c  O+ o7 S% X6 e5 y8 R0 O
  512. /************************************************************************/
    # T# d9 c4 G7 s
  513. unsigned long Jedec_ID_Read() ; N/ t2 x& Q$ K3 G8 h
  514. {
    6 f; d& ]0 c5 f; B& I# G+ o( n
  515.         unsigned long temp;' p5 K+ K& H& H) B! T* S( D
  516.         + W8 d6 T) n7 c- L- N
  517.         temp = 0;
    3 u* d% X  \: w; h. m+ e

  518. 5 O, l4 J4 t2 ]7 n% {+ ]7 L
  519.         CE_Low();                                        /* enable device */
      r' p' Q4 y7 {: l8 H+ q* {( Z. u4 b
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    5 Z0 F, _0 _% S$ A
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    . v7 |7 o9 M2 y0 h( N8 P* R
  522.         temp = (temp | Get_Byte()) << 8;        0 g/ T% ^2 S  i0 _" p  s
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    * ^: {. w# v! q* A
  524.         CE_High();                                                        /* disable device */+ y* l- m% D' J& w. F$ ^
  525. , |: r8 a. B( r# |5 G7 [! }5 ^
  526.         return temp;* P6 A1 r4 d( \' y, @/ [, M
  527. }
    0 l: S9 K8 L6 O8 J) N) m

  528. : x# e1 u& ]- [9 N
  529. /************************************************************************/7 a+ c# L, e& U* J  X3 S4 e
  530. /* PROCEDURE:        Read                                                                                                        */5 t/ y: }4 B7 [1 B
  531. /*                                                                                                                                                */               
    / O3 q3 ^; {, C# n# l& U7 G
  532. /* This procedure reads one address of the device.  It will return the         */
    # K' m6 j. t. C8 z1 c: _0 |
  533. /* byte read in variable byte.                                                                                        */
    " f3 V# |' w2 `: y5 P
  534. /*                                                                                                                                                */
    & l; W3 Z7 J6 s1 S
  535. /*                                                                                                                                                */
    , H3 g0 W  ]5 q7 A; m- y8 `
  536. /*                                                                                                                                                */
    / o( r$ S7 r$ F- c% s! `
  537. /* Input:                                                                                                                                */! N1 l' z, t0 D
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    " P7 }& u$ u5 u6 y" q7 F$ s5 l% E
  539. /*                                                                                                                                      */5 X- M, p. S$ d: b2 f# i' _
  540. /*                                                                                                                                                */
    3 d1 u% A3 h0 O& J6 Q* N( A
  541. /* Returns:                                                                                                                                */
    1 @# }7 q9 o6 S, t5 {$ q# K
  542. /*                byte                                                                                                                        */
    % r7 O6 W* l7 P
  543. /*                                                                                                                                                */& R; w& G$ `2 `, E( i, t; H
  544. /************************************************************************/' U/ q7 ~9 O( [5 N
  545. unsigned char Read(unsigned long Dst) ; a! ^  @9 u; [& d/ K0 O0 a
  546. {
    $ G1 i# y- y/ B1 p0 Y  c
  547.         unsigned char byte = 0;        2 i% }) F7 n- Z. @/ a

  548. . P3 y6 G0 g1 q) ]/ ^, b1 h
  549.         CE_Low();                                /* enable device */" V/ W4 ~# S- `3 H2 a, A  b7 Q
  550.         Send_Byte(0x03);                 /* read command */
    ' z. ], A$ q8 n5 q) M, F7 j
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */9 O- d8 S- ~1 j) i+ n' ?
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    7 I9 u( t7 _- j! r
  553.         Send_Byte(Dst & 0xFF);: K2 V! j  Z) Z5 n" k* m
  554.         byte = Get_Byte();
    # A! {5 G" R( Y  M* u: h
  555.         CE_High();                                /* disable device */
    4 U: X/ m  Q7 V; j8 [
  556.         return byte;                        /* return one byte read */9 i% `0 i0 ?+ T- g( N; I3 p7 c+ [
  557. }
    . A( |% i( [# w( Y/ T3 X
  558. ( I" M9 N$ Z: S2 R, |' _
  559. /************************************************************************/2 |4 Z. s' ]) p/ G  R
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    5 q( u" y) R! z$ n. g  }8 J* v5 \
  561. /*                                                                                                                                                */                ' z3 A2 ~$ c( L
  562. /* This procedure reads multiple addresses of the device and stores                */
    ! q( }% m( `! p  u" E5 l
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/8 h5 O6 A" p7 n
  564. /*                                                                                                                                                */  b/ Y8 P* ?2 B* ^2 k( _6 W
  565. /* Input:                                                                                                                                */
    " V( ]0 Y& B4 `2 ^( s' f8 a1 E5 f
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : x+ q& T; M7 o
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    + `2 `& N* }( z
  568. /*                                                                                                                                                */
    7 `9 x2 G" v" L
  569. /* Returns:                                                                                                                                */
    ! _# E) b9 b, p1 Q! M' I8 d. U2 D
  570. /*                Nothing                                                                                                                        */
    : ^, H& V+ e: Q1 M5 d4 K+ D# ]
  571. /*                                                                                                                                                */
    7 b5 k' m9 l  y" X( c6 e6 ~
  572. /************************************************************************/& M+ t' P8 q% g2 R3 p; Q
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    ( a) O3 Z5 S- Q/ k6 Q& y9 {" K
  574. {9 D% Q5 W, M  ?- m; Y
  575.         unsigned long i = 0;
    8 T% i& v4 f! [  {& A" Y
  576.         CE_Low();                                        /* enable device */9 W$ ^5 X" N4 {# F
  577.         Send_Byte(0x03);                         /* read command */( A) g" F8 T7 |4 W
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ) o# X* w2 e/ F$ s4 e: Z8 M
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));# q8 M5 `4 z: ]: y8 Q
  580.         Send_Byte(Dst & 0xFF);
    9 [2 `% o7 y; C
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    ! p8 o: K* G5 @2 P
  582.         {
    7 Y5 O6 U  u: H& I
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */. {% m" W  ~) W, V' s2 x' Z
  584.         }6 x6 P3 e& u# Y/ a# l3 I% i( E
  585.         CE_High();                                        /* disable device */4 u3 _" l. m: [! A' |

  586. * W$ X/ H/ i; q' P! Q* ]! q
  587. }/ c; `9 O+ [+ S% P
  588. - K# q6 [- N+ O( z3 q
  589. /************************************************************************/
    " y* l' ]6 G- F1 Q' N( N: ?
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */; C+ P6 r( Q9 f
  591. /*                                                                                                                                                */               
    7 g' m6 d0 ~/ b. k
  592. /* This procedure reads one address of the device.  It will return the         */& }; G6 v; t: U1 m9 F( B
  593. /* byte read in variable byte.                                                                                        */
    3 E' v5 D9 V. N
  594. /*                                                                                                                                                */
    2 F7 o% h' M8 k9 l( Q
  595. /*                                                                                                                                                */: {4 k/ K* q/ Y3 @1 `, |5 T
  596. /*                                                                                                                                                */
    $ I! \) I1 m% t9 z: e& U
  597. /* Input:                                                                                                                                */- Z; X, Z1 j/ _% Z/ B; e9 ^' Z# a, i
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    1 V4 G/ B( Z- M
  599. /*                                                                                                                                      */0 o5 J1 w0 g0 T2 T% o
  600. /*                                                                                                                                                */; Y$ y/ N' x5 W% p7 [
  601. /* Returns:                                                                                                                                */
    % d" e. Q/ {0 g" u
  602. /*                byte                                                                                                                        */
    : q7 l+ d0 a; x% A& Y
  603. /*                                                                                                                                                */
    , T1 }1 x2 i+ E+ k$ H( @
  604. /************************************************************************/( M$ N: z' C$ \1 F
  605. unsigned char HighSpeed_Read(unsigned long Dst) / o& e  }4 X9 O
  606. {# u0 d6 `5 d# \; T- |
  607.         unsigned char byte = 0;       
    5 t5 {! r& ?9 z) n" [4 p$ C& L; O

  608. / [* F# M5 t$ J# E. v/ ?2 U
  609.         CE_Low();                                /* enable device */" m6 L3 @: ^6 A5 M3 K! u* ]/ f
  610.         Send_Byte(0x0B);                 /* read command */: N& o& q4 G* y, M, D9 p9 G
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */* D' G7 d6 d! }) Q
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));2 ^5 n+ w1 w6 h& w% ~0 e1 V
  613.         Send_Byte(Dst & 0xFF);
    & N" F. P9 Q3 `9 q! w
  614.         Send_Byte(0xFF);                /*dummy byte*/( h9 t5 |! F. D4 }3 w
  615.         byte = Get_Byte();
    ) ?& x! d9 ]  H" ~8 |/ U
  616.         CE_High();                                /* disable device */
    ! D8 R6 D& }" ^
  617.         return byte;                        /* return one byte read */
    . y4 h3 C( b8 n3 U5 R% ~: P
  618. }" O3 b! y# o( a! d8 y8 n# R. z) Q

  619. + C) i% ^  M" K
  620. /************************************************************************/; x2 F! j" d9 O  D
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    : A7 \( l" J! Q
  622. /*                                                                                                                                                */               
    ; }1 s9 o# M' K/ u
  623. /* This procedure reads multiple addresses of the device and stores                */' R, X0 w: U+ @+ _4 j/ w0 W
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/! H/ V; c. R$ {8 D9 k4 o- `/ |
  625. /*                                                                                                                                                */
    5 h9 x" u$ V' i  m
  626. /* Input:                                                                                                                                */! G6 U. I4 \% q* T6 B2 H! o7 \" x
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    $ V6 L+ B$ i4 N" G" d; ?# u0 t
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */: d4 x9 A' v/ {/ H* k
  629. /*                                                                                                                                                */4 M! _8 O. b* F6 Z  _
  630. /* Returns:                                                                                                                                */: q, C: f7 ?$ c! ?. c1 L
  631. /*                Nothing                                                                                                                        */
    % n+ Z( L  W6 c; [
  632. /*                                                                                                                                                */* f+ r; I, l9 i
  633. /************************************************************************/
    9 q! u7 [7 o. i4 C$ |
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)* s1 |& A+ p' y2 E
  635. {) n5 d/ L! K8 Q- Y
  636.         unsigned long i = 0;  G# h" J! c( a9 I
  637.         CE_Low();                                        /* enable device */
    6 V' J- J8 q& B; e" ^7 @+ y3 J
  638.         Send_Byte(0x0B);                         /* read command */
    & K# C3 n. f8 x* i
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */, L- x1 a% w% f- F  h6 [& n
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    2 X0 r9 p* X1 B) n! \1 o, w; \
  641.         Send_Byte(Dst & 0xFF);4 r0 J1 ?& G! y8 }* z) N
  642.         Send_Byte(0xFF);                        /*dummy byte*/1 j# a6 Y: q6 l& \  V
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    * Z$ {- f8 d0 }+ Y0 o) b! A% b: C
  644.         {
    & h1 w2 Z9 R5 t4 t" v" X
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    2 F5 ?7 H" j$ {: G
  646.         }3 J5 F4 ]. |6 D! H1 @
  647.         CE_High();                                /* disable device */) O8 x) X1 M  N
  648. }
    ( P+ K( q: l8 U3 H* g* Q

  649. & q3 V" X& I0 C
  650. /************************************************************************/# Y# q0 r: v7 p
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    - x2 ?7 I, l+ V3 b( Z" p
  652. /*                                                                                                                                                */& @; T, r8 n( A0 ^! b
  653. /* This procedure programs one address of the device.                                        */
    ! r6 d# K* G6 Q' A
  654. /* Assumption:  Address being programmed is already erased and is NOT        */" g3 X$ I  N, R8 J7 V$ E5 n
  655. /* block protected.                                                                                                                */7 v* i; F: F5 W( N/ x& K9 a' j
  656. /*                                                                                                                                                */
    , o  @) R' X& ?0 I
  657. /*                                                                                                                                                */
    " ]; ?. \7 x" q9 B
  658. /*                                                                                                                                                */
    8 A" S2 f2 `0 a: ~1 Y
  659. /* Input:                                                                                                                                */
    / y" Q' L5 k7 d6 j) }' E) t; i
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    2 G% @: d! t  r. \
  661. /*                byte:                byte to be programmed                                                                */
    & e% X# B( }7 q/ _! P) [$ @
  662. /*                                                                                                                                      */" o- l) c; T  o) X
  663. /*                                                                                                                                                */
    3 T# E2 c. v  P! M4 \' H* Y
  664. /* Returns:                                                                                                                                */
    & r$ |( a# S2 I- r/ \
  665. /*                Nothing                                                                                                                        */
    6 P! n6 ?9 v+ U; r' P; Z
  666. /*                                                                                                                                                */
    5 K3 G* U! Y0 s! j2 n
  667. /************************************************************************/
    0 i5 i$ N8 c  k) k+ ^. u: d
  668. void Byte_Program(unsigned long Dst, unsigned char byte)) R8 j" x/ l" z0 T) D5 o4 ^
  669. {3 x, h& e+ \. b5 b; _2 w5 {' }7 `( ?; m
  670.         CE_Low();                                        /* enable device */
    9 m, z8 O* a9 F, L5 L* J5 h
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    9 ~$ ]# I( m' f! B- s4 c- u
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */7 d& W9 W* s* Z7 I9 l+ d
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
      G+ B$ p2 {. w: L
  674.         Send_Byte(Dst & 0xFF);  h( b( K- B5 i7 d& B! {
  675.         Send_Byte(byte);                        /* send byte to be programmed */* q: z0 n' |  _* V& N
  676.         CE_High();                                        /* disable device */+ K( N/ F: o8 g8 b2 E
  677. }4 _: @7 _/ d' V! S* i
  678. ( N0 S% C) x* j: G4 C! a$ F9 L: w
  679. /************************************************************************/  F/ i$ ^( B! U: |- S
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */% C  g- E! `1 B: C7 n
  681. /*                                                                                                                                                */0 g+ u' ?, X* K* J" J
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/% A* a, ]9 G( A* s9 Z
  683. /* the device:  1st data byte will be programmed into the initial                 */9 o2 t3 J7 E9 [$ G) z
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */5 b9 p+ }8 }9 V5 \, L2 h
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */# Z, M2 M& b# K: Q/ o6 K
  686. /* is used to to start the AAI process.  It should be followed by                 */8 f, t& {5 j# ?
  687. /* Auto_Add_IncB.                                                                                                                */. K' Y' C% U4 J) q4 M) d: o3 |) a
  688. /* Assumption:  Address being programmed is already erased and is NOT        */: s3 p9 F0 S3 Y, q6 g( O
  689. /*                                block protected.                                                                                */7 l; q( k0 l& Q& Z5 y
  690. /*                                                                                                                                                */% o5 Q. N* H2 M2 C
  691. /*                                                                                                                                                */
    5 H- B$ d5 _4 A: C6 J% M) @
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    * ?# a9 e: _5 T& k, F0 n
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    - O, E3 v- @+ u2 ^3 o! F
  694. /*         unless AAI is programming the last address or last address of                */9 H" V7 H# B0 `; |; `9 _- U( \. H
  695. /*          unprotected block, which automatically exits AAI mode.                                */" f' g. _& B" q) |: E
  696. /*                                                                                                                                                */$ ~" h3 ?+ ?7 R! u' }4 @
  697. /* Input:                                                                                                                                */5 U+ z* ]# ^3 s, T& p
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */' |: F- m" e; U8 f
  699. /*                byte1:                1st byte to be programmed                                                        */
    8 B( r$ L, P# z( [. v6 B$ H& _4 P
  700. /*      byte1:                2nd byte to be programmed                                                        */" W/ W7 M  A. C6 W' L
  701. /*                                                                                                                                                */
    8 V( n) w. r! C$ a* P( W
  702. /* Returns:                                                                                                                                */! X( }! t" a2 q$ a% P7 [% G
  703. /*                Nothing                                                                                                                        */% H% p% A0 F8 ]1 y  S, [
  704. /*                                                                                                                                                */
      @  {* I% z9 E8 l9 y; `& s
  705. /************************************************************************/9 w5 I% A* D. r# ]8 Y* q
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)  B3 b& [  n2 n  F9 U* K4 G2 R( g, w* c/ q
  707. {, F7 x, |' X  X0 C5 N
  708.         CE_Low();                                        /* enable device */
    % o) F6 b6 Z  @; w6 W" y. h/ D
  709.         Send_Byte(0xAD);                        /* send AAI command */
    % N7 R  g; q5 c& M9 C
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    3 N2 s6 c9 ~! x5 W- W1 n
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));4 t" @* m6 S5 L6 F
  712.         Send_Byte(Dst & 0xFF);
    ! h3 B. ]0 i9 }
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        ( C: I$ C/ J7 D3 S. F" a' g
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */; x, H) I3 t% \4 h& F8 P! S
  715.         CE_High();                                        /* disable device */
    . e% a9 y) K& w6 U" l
  716. }5 U! Y, L, r0 V$ \) T

  717. + R( @# g5 B$ Y& c1 k+ v
  718. /************************************************************************/
    ( {4 P( C; e5 a" [  v
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
      A6 U4 j/ F* |( s
  720. /*                                                                                                                                                */
    4 {' s* K0 m5 b; a6 w/ X2 m6 g
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    ; D  y/ ^- C8 _: M; C9 V0 G
  722. /* the device:  1st data byte will be programmed into the initial                 */( o' N0 f8 G8 Y3 T
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
      K, b* c4 ]( j; y5 y+ O
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    9 h5 o8 p( |& |
  725. /* is used after Auto_Address_IncA.                                                                                */% B2 D- U6 G! E5 e
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    ' w; _& v8 t5 @& z5 ?+ |
  727. /*                                block protected.                                                                                */" i* ^" a% H, C; ]0 ~
  728. /*                                                                                                                                                */
    0 I; v/ Y# S' t8 |- R
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */$ J; \6 g; `+ z
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    , [+ I) P  D$ v4 }
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
      `" R0 D- G& U
  732. /*          to exit AAI mode unless AAI is programming the last address or                */& B6 v/ s1 m% Z; _5 D) g
  733. /*         last address of unprotected block, which automatically exits                 */
    * M/ W1 `' S7 \4 F- A
  734. /*         AAI mode.                                                                                                                        */
    4 k; Q1 @7 \; S8 A/ o: K8 r+ q5 ~) y
  735. /*                                                                                                                                                */
    8 |3 N3 |4 U3 u8 x( S, q
  736. /* Input:                                                                                                                                */7 U6 v6 v% g) @# x3 X, k3 U
  737. /*                                                                                                                                                */
    , W0 [4 k5 x$ E( ^4 M
  738. /*                byte1:                1st byte to be programmed                                                        */( E: F# n" D4 j' D7 H7 E6 G
  739. /*                byte2:                2nd byte to be programmed                                                        */
    5 f1 W1 A3 H6 L# Q. r' I# b
  740. /*                                                                                                                                      */
    1 }5 [+ l$ _* _& K
  741. /*                                                                                                                                                */7 t! Z7 d" G6 Q7 i) d- ?
  742. /* Returns:                                                                                                                                */0 ~! ^" ?& d0 J3 G) G( u, I
  743. /*                Nothing                                                                                                                        */4 k) q8 G7 |( f9 E2 Q- M+ ]4 W! w+ h, ?
  744. /*                                                                                                                                                */2 U* p0 A9 P7 \/ v1 _  o4 {* V
  745. /************************************************************************/
    7 u3 e# s  }" g; G" U6 Z: v
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    8 H. w3 a8 \3 [. L% p
  747. {* f3 O, r5 z/ g9 e" r$ a' C
  748.         CE_Low();                                        /* enable device */0 V6 V! Z5 i- ^
  749.         Send_Byte(0xAD);                        /* send AAI command */
    & q$ Z0 R+ H1 Y
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */  p1 P% k/ _6 k* ~5 z8 p! V/ {: ?
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */% g. e- N' e, a8 I' P/ a
  752.         CE_High();                                        /* disable device */
    : J7 s9 l, ]" D- |: L. e  b
  753. }: U' X! ^5 o! |8 ]  C# A  v5 Y
  754. , a! K; I" |, i6 E" h/ m6 A
  755. /************************************************************************/; l  `! o9 `) l7 d# H
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */& |5 y2 L1 E& I2 W4 N* J# E
  757. /*                                                                                                                                                */
    ! l, W0 g5 S7 {! @9 _5 P! U2 D0 a- _
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */( c3 H  S2 w. Q; W) U: |
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    6 p: l  M" ^6 E) q
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */8 ^% l! _4 R  M/ r1 {, w
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    6 x6 p6 b6 B/ j* `+ A
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    ( @7 L1 ]. z. k4 p+ T2 b% N
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */. X' u0 [/ \/ ?
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */  d8 K! J5 _! ~  E$ B, C+ B
  765. /* Assumption:  Address being programmed is already erased and is NOT        */$ |7 a1 t% z; e) M( N
  766. /*                                block protected.                                                                                */* ~* m- `. F8 ~- u: c
  767. /*                                                                                                                                                *// W4 n" j. `" @% f" @; H9 \
  768. /*                                                                                                                                                */2 S  Y$ A9 v: `; i5 C) a9 F
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    1 B- k1 o" N4 R3 T
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */" |; ^/ p# o+ ?0 J1 |- u
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */: C2 V6 j& f9 q7 h
  772. /*          to exit AAI mode unless AAI is programming the last address or                */4 u$ |/ Q* q0 _+ a6 r. ]$ U
  773. /*         last address of unprotected block, which automatically exits                 */. y( o/ Y7 D2 v" D
  774. /*         AAI mode.                                                                                                                        */! |( S3 m) x! L( a% i
  775. /*                                                                                                                                                */! ~7 }4 _7 q3 @# T+ ?( o/ N
  776. /* Input:                                                                                                                                */0 |& n/ i# U5 n
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */! L7 b# D) U0 j' ~4 K7 s& V
  778. /*                byte1:                1st byte to be programmed                                                        */
    9 y6 T3 G4 O! e
  779. /*      byte1:                2nd byte to be programmed                                                        */5 y' h& }/ `) [5 |
  780. /*                                                                                                                                                */
    ' z9 t  `* p7 h: Z- Y5 G/ o5 s: m
  781. /* Returns:                                                                                                                                */4 ~, x# F; m7 z  q, d
  782. /*                Nothing                                                                                                                        */
    : H9 V# R5 w8 P0 Y4 [
  783. /*                                                                                                                                                */9 f3 C+ ^$ R* w7 Z% b5 y
  784. /************************************************************************/
    6 j6 l: N( o5 X0 G
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    1 _# d. m  {  s0 R, H2 `- h
  786. {# e# M1 h1 ~5 l9 r0 ]% w9 d5 k
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        : g! R0 d& C$ S4 o& j/ b
  788.   Z8 g- z4 {4 B$ `6 c4 o1 e
  789.         CE_Low();                                        /* enable device */
    ) Y/ ^  H- @1 I4 z9 w& |4 h# u# G
  790.         Send_Byte(0xAD);                        /* send AAI command */& U# P) ]! }  X" P7 \
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */5 ?3 N8 O) h9 J  ?
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    9 S4 _6 e2 ]* g+ y9 h
  793.         Send_Byte(Dst & 0xFF);/ Y8 \8 {' \! B; s: h/ H: Z
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    9 d: Q" d  k+ d4 x  l, d; k
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */; G9 C2 s  g1 W  ]$ H  n: P, n
  796.         CE_High();                                        /* disable device */5 n; H7 l3 W/ V. H" Z
  797.         5 S; _& Q- [" w. g3 x
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */6 U# o3 `9 k2 R  E; s1 j
  799. 8 H/ \4 @: f4 J6 S
  800. }6 K: N$ x5 G7 b- H( Y! E. |
  801. & K6 l* W1 K/ D9 j  B& Q
  802. /************************************************************************/, q+ S4 R( E( Y7 S" h8 y
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */# A3 w- Q4 N) x2 |, @5 D+ z
  804. /*                                                                                                                                                */) x& g- f' d+ M' N
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    2 ~, Q' }. @- x  S9 U( T0 h& t
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    * s, A' d& u1 H/ {1 }+ J
  807. /* AAI programmming is completed.  It programs consecutive addresses of */2 }, I6 a9 t2 l
  808. /* the device.  The 1st data byte will be programmed into the initial   */4 b; j' d5 n8 b- F, |
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    " i; U% D8 O3 f$ T* }7 U9 J) D
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    ) T& @0 j3 v; e1 ]8 N* {# y
  811. /* used after Auto_Address_IncA.                                                                                */
    " }" Y, ]8 ?, J0 e2 `: O
  812. /* Assumption:  Address being programmed is already erased and is NOT        */; s6 ~  B8 ?5 D( O/ m- Y
  813. /*                                block protected.                                                                                */. S1 o+ v  s9 T0 x: `. d/ {
  814. /*                                                                                                                                                */
    ! \* j& i  t1 p3 v, }
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    9 S5 |; j2 Q& k0 C$ J
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */. q* e0 {6 i( U; A- A0 F
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    - u1 B+ R) H- G' q
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    $ ?+ S  J0 k1 ^8 N
  819. /*         last address of unprotected block, which automatically exits                 */- g- v8 E9 ]8 u9 f1 f9 J
  820. /*         AAI mode.                                                                                                                        */- t6 L- M  z1 o9 g. [8 ]
  821. /*                                                                                                                                                */
    / m8 E! q" H! W; y* d
  822. /* Input:                                                                                                                                */2 ^$ U: [) Y8 ~7 a9 _) q2 M' _, [
  823. /*                                                                                                                                                */# k! r3 L+ |3 G
  824. /*                byte1:                1st byte to be programmed                                                        */3 u1 o7 ?0 G% j7 O# `  q# C
  825. /*                byte2:                2nd byte to be programmed                                                        */8 H1 n/ X) [! t2 R2 k$ v
  826. /*                                                                                                                                      */
    ! Z$ t& l2 O; g
  827. /*                                                                                                                                                */
    9 C  h" K8 `+ D
  828. /* Returns:                                                                                                                                */  M7 L4 Z3 p' J4 m
  829. /*                Nothing                                                                                                                        */
    1 e! b7 f$ p9 H- p  E
  830. /*                                                                                                                                                */8 K( d6 }5 h  k# B; b/ G: ~
  831. /************************************************************************/; d9 t1 z+ M& P/ K' e
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    . l- Q0 S( _0 r# \& z* M$ A2 {
  833. {/ B3 n- i# W6 q# M- `
  834.         CE_Low();                                /* enable device */' U2 x$ S* N/ y
  835.         Send_Byte(0xAD);                /* send AAI command */
    . e% S2 H# k+ |1 _* q2 C
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed *// P7 J2 m" S& M) Y1 W5 Q: w
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */0 `# e* W7 C9 `6 H% A( z! ]% ?4 y
  838.         CE_High();                                /* disable device */
    ) k8 x2 O' q- o4 q* Q% h
  839. . y2 }2 ^  f7 |: m5 z8 N* O
  840.         Poll_SO();                                /* polls RY/BY# using SO line */+ c: c# _/ f: y8 k1 X4 J( d

  841. ' e1 E9 L: ~) K; v- `$ x
  842.         WRDI();                                 /* Exit AAI before executing DBSY */) \: A: i; M' t* n7 V5 F9 I
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    / I+ t/ N  A5 H( V( d- A. `4 D4 z' M
  844. }) \1 v& l3 N1 i0 z3 M- C) O1 r

  845. + d/ {* @6 ]& L/ G( k  U" M& V: R
  846. /************************************************************************/
    6 P% W& l7 ]% g1 t9 V
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    ' ~) b0 s, b4 k: X
  848. /*                                                                                                                                                */: l  A) ^4 s/ c  w
  849. /* This procedure erases the entire Chip.                                                                */
    2 @! L/ |, G: G0 H' m: C- t! m
  850. /*                                                                                                                                                */
    5 F) D$ \3 F4 @$ G$ f: Z1 |+ s
  851. /* Input:                                                                                                                                */1 v2 U7 \, f% q/ ^4 J4 C( M6 Y
  852. /*                None                                                                                                                        */
    % o  o1 H' g1 _9 I9 M) P9 {
  853. /*                                                                                                                                                */
      ?* Z( \4 `! Q
  854. /* Returns:                                                                                                                                */
    ' r$ \9 s! F+ x7 o4 V$ T- D! h
  855. /*                Nothing                                                                                                                        */
    # z7 f0 J2 [2 V( S1 n# L
  856. /************************************************************************/  y3 L( h, L$ K
  857. void Chip_Erase()
    . L- T% q- n$ z1 a0 k- m
  858. {                                                ; J1 z6 i3 u, @+ E8 L7 d- Z
  859.         CE_Low();                                /* enable device */
    $ S* z$ S* R5 w: ^% y+ a
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    : h' ~* S4 G9 c" l% O
  861.         CE_High();                                /* disable device */
    ! E2 K. Q: q, t7 c# k
  862. }5 q% g8 x* e; ^' \4 c. Y

  863. 9 W) L1 k- l0 j" R
  864. /************************************************************************/( X" q7 E  w9 U6 w
  865. /* PROCEDURE: Sector_Erase                                                                                                */) L* m# k7 y+ ~; e' z/ m; G
  866. /*                                                                                                                                                */! A% T6 Y3 q5 t3 e
  867. /* This procedure Sector Erases the Chip.                                                                */
    " u5 R% y$ }' D
  868. /*                                                                                                                                                */; o9 e" y1 k- x# o0 o
  869. /* Input:                                                                                                                                */% o+ r/ N; [2 E7 C9 U" l0 O
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * Z8 R4 m, r- J
  871. /*                                                                                                                                                */* u5 `0 ~4 j( ~9 r0 N9 G5 b
  872. /* Returns:                                                                                                                                */
    0 E# o4 [# V' ^
  873. /*                Nothing                                                                                                                        */8 D$ z) V* H. T2 M3 K* e  H/ w% A
  874. /************************************************************************/
    ' z' b" M0 }8 g7 r2 E/ P
  875. void Sector_Erase(unsigned long Dst)
    / m8 L) q9 I# ]. \# M
  876. {
    $ O5 a. U$ K0 a: v* s, g4 I* I

  877. / b3 L: `, d- a8 `% w1 `

  878. ; W4 B. `+ N: I4 H! r
  879.         CE_Low();                                        /* enable device */) q* X3 a& r7 W6 C( d# N' {
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    # f' C  B  A* u0 o/ [; Y+ \6 o; i
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */, i3 l" M, ?+ {* @0 Y& e
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));) S. v& \9 g! f  |) N+ E5 [
  883.         Send_Byte(Dst & 0xFF);
    . r7 K1 x- U2 H) E. P& v
  884.         CE_High();                                        /* disable device */" q/ a9 l- j1 P5 ~
  885. }        5 W$ c! X) ]2 u, ]; D2 k$ Z+ S8 J

  886.   Z/ H. p5 `  I& F7 @* O/ A
  887. /************************************************************************/) N* o( b4 g6 s0 M" B0 p
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    , ~# b% ]9 }, W, {3 a1 D- c. y
  889. /*                                                                                                                                                */; K+ z  b) C2 l1 N6 C% K* w
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */8 X1 `, B" y, }& b' D1 y
  891. /*                                                                                                                                                */( [) t* c$ K$ v; e$ q  W6 f- o' K% p$ r
  892. /* Input:                                                                                                                                */
    + {' e8 S- G! \+ q+ R" u, F
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    $ D& d+ q5 E' u- f, C0 u
  894. /*                                                                                                                                                */
    $ m4 G6 S) T9 X0 q8 k$ e8 [
  895. /* Returns:                                                                                                                                */) X% R5 R6 I2 X6 [
  896. /*                Nothing                                                                                                                        */% C. w! M7 h6 g. w" o! W
  897. /************************************************************************// N# r; c7 R. ]" T( L+ p$ k# f
  898. void Block_Erase_32K(unsigned long Dst)6 f4 x: N( r- j: e4 W/ `0 r) X2 O
  899. {/ {8 ^) `; N( K; h! G1 F% c$ m3 w
  900.         CE_Low();                                        /* enable device */& m; m+ }+ G! u% N
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */9 E. E- x- }7 P+ V/ R
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ( A& _% b- V( K+ L; Y9 Z
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    0 a; H# `) ], j7 }9 U, S. y* @7 J. y
  904.         Send_Byte(Dst & 0xFF);
    % f0 |9 x- b. D. Y( l6 Y
  905.         CE_High();                                        /* disable device */
    , F2 z6 D& |5 V- j4 f" }& k
  906. }" p! z7 g6 b4 I) [
  907. ) G8 H1 m; E/ l
  908. /************************************************************************/2 ~- S5 x. p9 U) ~5 u) J; l
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */' s% [, W$ b6 X7 _% B" r
  910. /*                                                                                                                                                */
    , N9 H4 r# c8 }* G
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    5 J1 T& g. ^8 D, L0 J+ B/ {# H0 `
  912. /*                                                                                                                                                */
    1 g$ r/ |) g) Q  S
  913. /* Input:                                                                                                                                */
    * ]/ [+ o2 I- u- `* J# Y; K$ _: f
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    $ t/ p6 T0 D- X3 t* z* H3 a0 A
  915. /*                                                                                                                                                */0 `: P+ o- ]9 X2 J* K  K% i9 |
  916. /* Returns:                                                                                                                                */9 n, q0 s, c' R( z; y4 m
  917. /*                Nothing                                                                                                                        */
    : [4 o4 H! i2 e" F* Z# v) I" b7 Q
  918. /************************************************************************/: ]" F  u  t: j1 V  Y# X7 Q
  919. void Block_Erase_64K(unsigned long Dst)) G) |0 j1 s) Z$ T2 J
  920. {! v! {; m/ g+ a, r, \# D& h
  921.         CE_Low();                                        /* enable device */
    " r, [+ t) |7 g; z3 f* C+ A
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */" c4 ]+ e- p, R% k+ q
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    * d% L) b0 a1 W" l5 b. f
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    $ V% f6 B! o. T: S; W
  925.         Send_Byte(Dst & 0xFF);
    " a: C2 N) U( a7 _# T/ p
  926.         CE_High();                                        /* disable device */
    7 ~6 p6 ~# d: K. w! @1 @
  927. }# F  C9 p: R, z
  928. ! h" g  Z$ N/ b+ \' i
  929. /************************************************************************/
    4 Q0 ~* y, P4 v
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    4 B4 H- H! h" D1 s
  931. /*                                                                                                                                                */
    $ e, o% l! J+ O: s4 `& X
  932. /* This procedure waits until device is no longer busy (can be used by        */
    & a% S& X3 L- ~
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    # o  @' w4 H+ i% n1 ~, E2 Z) Z/ O" {; C
  934. /*                                                                                                                                                */& r$ G( ^2 r& w2 @8 [
  935. /* Input:                                                                                                                                */
    6 Q+ V' l- @; X8 I
  936. /*                None                                                                                                                        */$ v% O4 v2 s* W$ C! d' I7 p1 l2 `1 m
  937. /*                                                                                                                                                */; r- s  T! r4 d* R, \
  938. /* Returns:                                                                                                                                */
    # k2 a* k. q; m5 y9 }; T
  939. /*                Nothing                                                                                                                        */) k" l" i# R2 o9 G6 O% W9 f. E
  940. /************************************************************************/
    1 J* n* r7 r  h; _
  941. void Wait_Busy()
    $ e* Q7 E- p' f4 Y6 w8 X& n
  942. {
    ' J$ T1 v) Z- k: W5 ]/ i; ^
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    , t6 d( S% L+ _! J- r! B: w5 A
  944.                 Read_Status_Register();
    3 I  D! R. L) r/ p. \7 U+ L0 Z% j5 J9 F
  945. }4 i3 W, k! `" f1 \) Y  I
  946. ' C9 Y6 A3 o* G) {. I( E/ Q  @
  947. /************************************************************************/
    ) S- U% ]2 X: Z' n0 ]4 L
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    1 g2 D% @3 F5 o! h3 b2 C
  949. /*                                                                                                                                                */
    * G0 Y4 y2 u- I' \8 O! i
  950. /* This procedure waits until device is no longer busy for AAI mode.        */# X0 y: r1 S# I
  951. /*                                                                                                                                                */
    * y0 `" x, j/ W; [  a( f
  952. /* Input:                                                                                                                                *// H/ q, @% o9 a( j; g6 B% g; O
  953. /*                None                                                                                                                        */
    5 S2 |8 z+ Q9 y
  954. /*                                                                                                                                                */% `% u. }+ E4 S7 L4 q& k
  955. /* Returns:                                                                                                                                */6 z% ]" \/ u" d3 @, v; c9 S$ i
  956. /*                Nothing                                                                                                                        */
    + W7 {: ?, O$ G4 W
  957. /************************************************************************/
      d* Q7 N+ g0 o3 X- W. B
  958. void Wait_Busy_AAI()! r2 u/ h4 d, L4 D
  959. {" y3 X2 y  ]. i. p
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    7 z! I# c5 E2 \" i. Y+ D( \
  961.                 Read_Status_Register();  O3 g" Y8 z+ h
  962. }
    % h3 Z+ ^$ S: G4 ~% p0 B
  963. : O+ N+ C2 `0 m5 e# r7 S1 K) Z
  964. /************************************************************************/8 g8 ^0 s3 k- x6 e6 B
  965. /* PROCEDURE: WREN_Check                                                                                                */
    ( t( r1 u2 T6 R) z
  966. /*                                                                                                                                                */8 X& K8 R9 M2 [9 s+ F' s2 {- `
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    . J3 w. w3 G" Q+ n
  968. /*                                                                                                                                                */
    6 L5 N3 r9 m0 q
  969. /* Input:                                                                                                                                */
    3 D& p0 p3 p7 c2 ?* @( A  s
  970. /*                None                                                                                                                        */
    $ L. B+ Q3 H3 }9 \6 N
  971. /*                                                                                                                                                */0 f! M0 j. E4 J1 O, P$ q5 J- ?5 S2 T
  972. /* Returns:                                                                                                                                */6 Z7 D2 m! a) O
  973. /*                Nothing                                                                                                                        */
    " X7 ]( L7 S0 `) Q1 `8 W
  974. /************************************************************************/  E; `% ^0 c( i5 ]# c
  975. void WREN_Check()
    # E" V3 b( ^# Y; s! L
  976. {4 l  A4 I, R) s! h: k5 k
  977.         unsigned char byte;, {6 g6 e, n' @
  978.         byte = Read_Status_Register();        /* read the status register */
    - n; X1 ?! u$ c8 K1 v1 S. |
  979.         if (byte != 0x02)                /* verify that WEL bit is set */6 P- y, x9 Y0 I0 w$ R4 B
  980.         {% e9 \1 s6 u5 Y6 v' C7 d
  981.                 while(1)
    4 ?( D/ {3 q4 q) @3 `
  982.                         /* add source code or statements for this file */
    / d. a4 Y2 k& |9 h4 i! B9 [) U
  983.                         /* to compile                                  */3 ^& g- V3 x, x: h! `
  984.                         /* i.e. option: insert a display to view error on LED? */) T+ y  g& p0 z9 p
  985.                  
    ! A: `+ J' [! p5 A3 F2 m9 }
  986.         }* {! x: m% c* \" X# I
  987. }9 D. j/ {3 V( a/ ?# z9 [0 N' O

  988. ) b3 A: y3 x1 a6 [
  989. /************************************************************************/+ x  ~0 W* _' U) C. }. d+ Y
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    . f1 n+ I2 F) D% U
  991. /*                                                                                                                                                */
    ' G2 q: E- _# `( f  \8 r* R+ T) {
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    ) \/ |( s6 Q" Y1 w6 K7 C- b
  993. /*                                                                                                                                                */
    2 x4 u8 N& y$ D3 \* ~& A
  994. /* Input:                                                                                                                                */
    , S. ?4 Y. x6 n4 ?5 Z
  995. /*                None                                                                                                                        */; Y6 ?+ {/ K. ?% f
  996. /*                                                                                                                                                */6 \4 L" C$ J0 I) m
  997. /* Returns:                                                                                                                                */
    0 D# _$ [6 \* N0 h9 T" }
  998. /*                Nothing                                                                                                                        */; ]0 q# _! p6 E1 K2 r+ S5 R! r# e
  999. /************************************************************************/8 D  k5 W) m* P9 d7 O8 B
  1000. void WREN_AAI_Check()
    ' H4 \* {+ T4 l+ `
  1001. {
      U/ C  W8 \2 B* r
  1002.         unsigned char byte;
    $ Z6 g$ N: U+ D5 s
  1003.         byte = Read_Status_Register();        /* read the status register */, ~* ]; x& G  d( h9 _; Y
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    5 q/ @- ~% j) L1 z, x/ _
  1005.         {
    * s1 ]' ^) f1 z
  1006.                 while(1)                % u7 E4 p+ b6 l/ i& j
  1007.                         /* add source code or statements for this file */
    # E$ G6 @/ h2 A1 S3 q
  1008.                         /* to compile                                  */
    . H* q/ x$ {' P) t
  1009.                         /* i.e. option: insert a display to view error on LED? */$ b9 x% F% l/ N5 i& }8 z+ g

  1010. & n7 [8 P5 m: F2 a
  1011.         }8 `: x8 d& q% |. F" ]) _, x. v# L
  1012. }- z- v+ U1 t2 k0 W+ r
  1013. : d5 {' d+ a- _* f, a; O
  1014. /************************************************************************/
    ) N4 c9 ^3 Z* v5 p, E. g
  1015. /* PROCEDURE: Verify                                                                                                        */0 q0 q  k9 E1 _/ B/ [/ U' C7 S% I7 T
  1016. /*                                                                                                                                                */3 J' \- Q! f0 S8 I5 P
  1017. /* This procedure checks to see if the correct byte has be read.                */
    + E3 t) }) u/ s# \* J9 k
  1018. /*                                                                                                                                                */
    9 V& ^! b. J" g
  1019. /* Input:                                                                                                                                */9 a, J! R6 |2 q( g$ i4 ?. u
  1020. /*                byte:                byte read                                                                                        */
    ! v. G2 d5 S9 u" ]
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    9 \1 j( h3 q/ C- h. s0 x. c+ G7 F
  1022. /*                                                                                                                                                */4 y# G3 `( b9 M* g
  1023. /* Returns:                                                                                                                                */3 ^, q6 X+ G- N0 u/ l( b
  1024. /*                Nothing                                                                                                                        */
    : ^) w$ o1 g, }5 b' I3 x6 Z$ j# t
  1025. /************************************************************************/: H3 a  A1 D* _4 |' b9 p
  1026. void Verify(unsigned char byte, unsigned char cor_byte)8 H6 P& G3 S$ d1 M* S9 Z6 E$ C
  1027. {6 Y5 Q' E# A$ R! E
  1028.         if (byte != cor_byte)7 I; D5 P1 R4 X' r3 S2 X
  1029.         {8 ]6 @) v5 i# M9 Q& ?1 F
  1030.                 while(1)
    ) D' U: ^4 F4 m2 ^2 f( b2 U) B
  1031.                         /* add source code or statement for this file */
    9 B/ d: j" W" X* Y; }' _1 `
  1032.                         /* to compile                                  */
    + h" u6 p! b; m& u4 r9 B, |: }1 F" T$ g
  1033.                         /* i.e. option: insert a display to view error on LED? */; b& r0 |5 S8 O5 X% {# B7 L
  1034.                
    ! k& a1 X  F$ Y4 Z- Q
  1035.         }
    5 e4 U  Q3 ~# k5 R% |- i; j! h
  1036. }4 p" u" z9 |2 c% y" M# R

  1037. 5 Z2 E+ F( L* ~9 L

  1038. 9 e5 y1 q: e2 x, X3 I
  1039. int main()
    1 X$ a7 r! e! N! s: H
  1040. {) y: A4 I4 }( J, Y/ Y/ E' }

  1041. 5 m( l6 o1 k+ [7 j" ^2 b) J. J
  1042. return 0;( R: W' v5 `! k: J# V  b" ?
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:5 I: S+ W& ?+ p, x8 f8 I" L, V
   main()
, G9 X2 D0 D# D# ^   里面怎么是空的呢?, i  K# G. ?0 W* L
   发一份给我吧# W8 |5 X9 \( D/ t
mail:luyijun2005@hotmail.com$ h& N/ a" `' e+ u# v$ f/ {8 O
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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" a- O6 K+ N$ D
# {/ S2 ?; C; r% y) T7 J# u
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。- K2 |. b5 O/ D: y- _3 `
EC的代码在哪跑,你看DS的说明,每个EC都不同的。
. n$ w8 S, _' M4 H2 R1 a9 U& w$ tOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?, E! f  g4 e, g: B# I! M5 l6 T
上面几个问题是你没看任何东西而白问。
9 Y- J, v: @# Z- Z* I/ Q. a
" e0 [( ~7 P, U& I* D: u, F9 L至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
0 o* `8 J9 T) n8 G6 Q
/ Z% w& q9 y) i9 v& c5 S+ S关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!; p, v# R1 S1 l: o! j3 V

3 n' l* A+ C: {5 I, d关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
# q8 k* H* O& H9 {, Y! p; n
$ m6 s0 [- k- A4 O2 k( l4 ]关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...5 |, y5 K2 q. `
8 C, I: h+ W! p6 ?
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
2 Q: i) C7 X1 \似乎要把SPI能support 到最大,这EC chip应该有好卖点0 p( m. f  N  X* ?; k% a9 r
BIOS功能要不要强大,也就决定了SPI Flach的大小
. V0 _! f, I1 I+ L: [6 R" n我是这么想的~让OEM去决定要挂多大!
. q) V- w( i" u$ X" V) c如果我司有BIOS工程师就好了~哈, d$ ]; |) R3 u  d) W2 v# j. Y, ]* ~# n
WPCE775应该算很新的东西,来看它支持到多大?0 X$ X( u6 i. e# q% |
- r+ y/ ]4 p/ ~/ y/ @3 S
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
1 \  ~7 F+ j( W( o5 R其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
" ^6 f+ t. ~* ]2 n# z' Q8 c7 y: u7 _
  b2 H: o4 u6 Z5 c2 J) D( o这份driver收下~希望以后有用到
8 v4 t( {8 X7 k, G谢谢bini大大5 F! ^+ ]& b6 O! L6 S5 D; n
$ \! a7 z$ s% @" i9 W
很新很新的新手,如有错误请指正 (准备看第二家的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()
( {. ~+ |, K( n) `{
! [5 `0 |# P5 e# D3 b        unsigned char temp = 0;
6 t: T0 v' ]* C  O        CE_Low();. |1 ^; z* W* P
    while (temp == 0x00)        /* waste time until not busy */
' A4 Q  U: r+ ]. e+ Y" u                temp = SO;
* a& b' l# }0 I1 d: c. ~        CE_High();; n+ G; }" {# {" P
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
2 j2 b) u# B8 y{
2 T) Q9 i2 x8 j$ k        + }% w6 a6 G4 X4 z5 D
        unsigned char i = 0;4 ?* y: M$ b9 f8 l) X
        for (i = 0; i < 8; i++)
. k( R, W' T1 M# m        {# C9 h' F) f- f/ f6 ^
                4 {2 o' s, e4 m; `5 E5 H
                if ((out & 0x80) == 0x80)        /* check if MSB is high */$ }# X6 b) N8 U
                        SI = 1;
9 r9 A8 D0 D# _# K) o+ R( T                else% s" X4 X: j+ Z3 d9 x4 j
                        SI = 0;                                /* if not, set to low */
! B! ^; ^' T, q+ Z 问              SCK = 1;                                /* toggle clock high */  O/ [  f+ H, e" h) m7 b/ x
   题            out = (out << 1);                /* shift 1 place for next bit */
* K9 _  h) T& w$ N% }: r" ~                SCK = 0;                                /* toggle clock low */
! h  _9 |3 f1 d: {1 h2 t( p# l        }: b5 x; O# Y' ~; v
}5 K8 X# m" e. H: K0 Y4 T
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-13 06:44 , Processed in 0.066273 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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