找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55181|回复: 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' E, c6 n1 O$ b) F- }

  2. ) \# c3 }1 {7 E
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    6 n/ \  v5 n5 j2 b' K1 R! k$ Y

  4. 9 @, r! h! N0 S8 |% J# k4 L
  5. November 4th, 2005, Rev. 1.06 B3 `6 U8 A% ~, g1 q! h+ C8 J
  6. 8 R0 Y/ R- [- [$ |
  7. ABOUT THE SOFTWARE5 i8 |0 Y* k" H) [$ ]
  8. This application note provides software driver examples for SST25VF080B,6 z$ G' `" c/ m4 Y7 L
  9. Serial Flash. Extensive comments are included in each routine to describe
    # Q  b: Y' |3 Z; r: h' p1 s
  10. the function of each routine.  The interface coding uses polling method
    3 ^+ s& U2 x0 ~* K* C+ S6 P
  11. rather than the SPI protocol to interface with these serial devices.  The
    8 ?. t# F6 I, T
  12. functions are differentiated below in terms of the communication protocols
    % o; A) ?/ {0 w) P) D# E
  13. (uses Mode 0) and specific device operation instructions. This code has been 7 P- v9 Z3 I/ ~6 h
  14. designed to compile using the Keil compiler.
    9 w& E8 `7 b: @/ z" S0 u
  15. % n! N8 q( i7 d0 A

  16. 8 n( t0 h3 @5 i+ d( k1 U
  17. ABOUT THE SST25VF080B1 B* }. T2 z' K+ U2 h

  18. 5 T, ?4 `1 C6 i# i6 J2 p
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    3 L! r% v' e1 Q# F
  20. conjunction with this application note for a complete understanding
    9 t8 a( [( R! ]' L# V5 q! k' l4 T
  21. of the device.
    : f0 Z$ n% V+ V- g6 c. h

  22. * B' ^' Y. u( b
  23. 3 w3 v* ?+ M7 T7 N7 a: l
  24. Device Communication Protocol(pinout related) functions:
    . B/ ?, b3 p0 \( v3 J1 A1 k

  25. 3 I3 C. l3 z* H) g; P6 E
  26. Functions                                    Function
    . \* l' `) P+ R
  27. ------------------------------------------------------------------
    " q+ _# n; B  B. [
  28. init                                        Initializes clock to set up mode 0.9 H; D3 b. ]1 c7 h# G8 I8 k9 {
  29. Send_Byte                                Sends one byte using SI pin to send and $ H7 K  a' b" V7 ], i0 Q. t
  30.                                                 shift out 1-bit per clock rising edge
    - {; _& A7 Y9 v3 h
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    6 K1 X5 q( \8 X! o5 K- o
  32.                                                 in 1-bit per clock falling edge$ y% A% u0 W' U  `6 F
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    ) G  _- {1 G: `2 F$ ?
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    ( x7 J  t4 R) w0 @: W& H% ^
  35. CE_Low                                        Clears Chip Enable of the serial flash to low: F5 r6 V; ~6 l/ J3 v1 A6 v4 M% l
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    ) p: E+ ]+ g  P, N7 U; ^* g
  37. Unhold                                        Unholds the serial flash) p3 o  ]0 A; f4 r2 y: w
  38. WP_Low                                        Clears WP pin to make serial flash write protected) |1 h/ A! H# N, l7 V0 u1 _
  39. UnWP                                        Disables write protection pin
    " h$ X$ C# o& d& E/ e% N- Q4 U$ W

  40. 2 Q" c" Z& Z6 g7 t, b
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code$ C# S- V( o+ v. P4 i6 {
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your- r% {' P3 A( r2 }' \$ ~- q
  43. software which should reflect your hardware interfaced.          
    2 N, N6 K# N/ Z6 ?3 r( f

  44. & q# R- T1 z# W5 I8 @! }/ m! T0 `

  45. 6 a  m6 p1 j1 Z' s) N
  46. Device Operation Instruction functions:
    ! J5 _- a! n) s; w% m9 s( G. K( G

  47. 2 E7 \0 I$ a/ e/ {- N
  48. Functions                                    Function
    4 M6 l; ~( V0 x
  49. ------------------------------------------------------------------0 V# W7 y$ n0 R4 l& \8 h: {
  50. Read_Status_Register        Reads the status register of the serial flash: n9 x! X2 [7 {! {% B
  51. EWSR                                        Enables the Write Status Register
    ' \3 x+ u3 ]1 f
  52. WRSR                                        Performs a write to the status register
    0 r3 U) ^6 j. t' E* M+ h  @0 @
  53. WREN                                        Write enables the serial flash
    ! `6 `/ A2 R9 k
  54. WRDI                                        Write disables the serial flash6 ]; Z% o6 _4 f6 A0 [0 E2 _
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    / ?. S- \7 j( {( j2 N/ T
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming* A) K" i, @) Y& P2 m% b
  57. Read_ID                                        Reads the manufacturer ID and device ID& E$ m0 b( ^; j* a: E
  58. Jedec_ID_Read                        Reads the Jedec ID: w! q( c* ^6 d. n2 K, b5 l# D
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency). X  ]* \. a, q/ [% H
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)2 u' {0 R5 A) l' n% _
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    , C4 {3 [3 l( D  X2 e* c6 f* r
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    0 k/ a8 a, _% X
  63. Byte_Program                        Program one byte to the serial flash% J6 @% o$ @3 a" Q" W2 s
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    2 b7 N7 \1 [% v( m' g1 f. T: {
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    1 n- k1 `0 x' T6 Q, G
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY: n' v+ [$ w4 ~! ?! G
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY# c; M( z4 z9 m( q3 _* v
  68. Chip_Erase                                Erases entire serial flash& |9 ~7 ]! ~( n& u' O% {9 L
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    7 M; U" F: {( @! I+ E) A; a% i5 E
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash2 D- R* m7 v& b, e
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash; E' _8 s+ Z" A* {# E+ t
  72. Wait_Busy                                Polls status register until busy bit is low
    8 i+ R3 V3 F9 l2 C
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming% g8 h+ x% ?+ v/ z$ s( d
  74. WREN_Check                                Checks to see if WEL is set
    - |" `/ ~/ _5 s: P& w2 \! W$ p
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    7 |9 O$ u" T- F

  76. . x/ s+ V1 u- g& }. O9 P- s
  77. 9 K% A+ [/ E! Y8 O3 l* C6 q

  78. 2 s, b5 x% @2 L% ^% Q! V
  79.                                                                      
    : P3 n: `' P9 F+ \. u$ v7 ~
  80. "C" LANGUAGE DRIVERS
    & @8 [/ o; }& R; b) W( G- `

  81. : f: r- ?) t; r7 O
  82. /********************************************************************/1 \: v# o% [; a1 Y( ]. _
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */$ E* k0 s) S- w
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    1 L& q& y1 |$ h) Z. V. y( K
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */- E4 V" N# w+ H- [
  86. /*                                                                  */
    2 g2 Z3 j/ c: J
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    0 D' H1 z# K  {( i6 V
  88. /*                                                                  */& w# e8 r( W: y! E1 S. l& k6 ?
  89. /*                                                                                                                                        */& ^# X0 {: n/ O
  90. /********************************************************************/0 D& |/ V& K( V. Q& {# _- d. _
  91. 1 }3 w3 c8 Z+ j, V' o! v& K. d
  92. #include <stdio.h>
    . V6 d7 _4 _; A0 ~7 ?" S: {
  93. #include <stdlib.h>
    8 M% y- C* _" ~/ x
  94. $ y* X% W+ v% b3 g! P4 a
  95. /* Function Prototypes */0 L4 k* ^" |, x9 E
  96. ; r( d8 R. }" h. v- A* M) d! d
  97. void init();
    ' B+ |2 V5 t1 {2 P' }# N
  98. void Send_Byte(unsigned char out);" q: P& N9 Z7 J/ c% x
  99. unsigned char Get_Byte();
    9 L' m/ F& B. N5 z: ?3 b
  100. void Poll_SO();% w% p4 X" c2 c& S, F. p! J
  101. void CE_High();# O) u; s; c5 Y0 h* w3 E( ~
  102. void CE_Low();6 ^$ m# I3 v9 @  V4 E4 {6 ?
  103. void Hold_Low();* s! h3 _+ C/ c* [& S! \2 p
  104. void Unhold();# F: ^, N% P, }0 y; r& w
  105. void WP_Low();
    " a; U2 H0 Z# E
  106. void UnWP();
    & [1 c# |% _/ A0 X7 t7 T' D
  107. unsigned char Read_Status_Register();
    1 U7 H6 a+ E. \- n! x1 r4 u6 M9 a) J
  108. void EWSR();- y6 w) T8 H, X7 s* n
  109. void WRSR(byte);
    8 {9 R: T; H$ |% c% F( R
  110. void WREN();* U" ], W" R) d9 G8 J9 r* k7 }* \
  111. void WRDI();% K! R; l% Z1 N1 O; T
  112. void EBSY();' o( \! [/ y/ a
  113. void DBSY();
    9 g! L' f; G0 x' |* j
  114. unsigned char Read_ID(ID_addr);
    7 }' O" i7 f& P! {* @
  115. unsigned long Jedec_ID_Read(); 4 i+ C. R% Q/ R
  116. unsigned char Read(unsigned long Dst);' r% U1 c- H  A0 d) j
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);/ S4 S# p3 J/ P( j# _
  118. unsigned char HighSpeed_Read(unsigned long Dst); 2 H7 Y% }' m! a  ?: V+ z& K
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    ) A# H: G0 `6 D0 p
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    . y/ F/ L  w! G% h2 Y
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);8 g0 \# u1 T, J  r
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    / K1 V5 @/ d  A$ a3 e6 i- t
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);, j+ z, m' e- s- f- p; V
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);# [, E4 N+ |2 {$ K
  125. void Chip_Erase();  f1 A) o) M' f, t
  126. void Sector_Erase(unsigned long Dst);
    + z: z/ X0 Z* }/ H& R4 b, n7 s
  127. void Block_Erase_32K(unsigned long Dst);) Q1 Q- c: C. Z3 p+ J
  128. void Block_Erase_64K(unsigned long Dst);
    * ?. s9 q) l/ ~+ ^  e
  129. void Wait_Busy();
    . q. M& i$ u. I2 C8 i5 P! s
  130. void Wait_Busy_AAI();" _# k, J: B1 ^3 }0 o* j
  131. void WREN_Check();) X0 m+ I: I' d4 E4 ?4 a
  132. void WREN_AAI_Check();( G5 i) S0 `4 z1 }& t

  133. 6 C' i0 ~; X8 F
  134. void Verify(unsigned char byte, unsigned char cor_byte);+ Y5 E, ^, I- Z  O& W5 [7 H
  135. 7 x3 r# F4 ~. Y! Q4 ?
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    # X- x6 a4 X$ h
  137.                                                                                 /* to upper RAM area from 80H - FFH *// E7 V; }8 r9 z; T% E! |
  138. . l6 h, J* y" y' D: V
  139. /************************************************************************/
    9 d$ X; l+ m& A9 X. x
  140. /* PROCEDURE: init                                                                                                                */$ I2 B* _9 C; y* T) Y
  141. /*                                                                                                                                                */
    / U5 F( j+ U. m( P  q0 `) n
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    , m# ?0 f+ i9 |4 ^$ q% w2 o- I1 \, m& U
  143. /* setting up mode 0.                                                                                                        */
    8 T: r# J+ ~( D9 _6 Q3 E
  144. /*                                                                                                                                                */
    - L7 z4 g' l8 t' Z. y, N0 X1 m  H
  145. /* Input:                                                                                                                                */5 ^( f6 I) d' s! p
  146. /*                None                                                                                                                        */
    3 I+ U. I6 Q; Y: T7 p
  147. /*                                                                                                                                                */6 W; `2 a( K4 F- J' Q
  148. /* Output:                                                                                                                                */
    1 t* I3 `# q; V* z/ q
  149. /*                SCK                                                                                                                                */4 B9 j7 Z% ?- O8 m
  150. /************************************************************************// d3 }7 x9 z/ P: t) x: n
  151. void init()
    " A1 r* ?: n5 `8 C( f) U
  152. {
    " f" L+ m8 H/ a
  153.         SCK = 0;        /* set clock to low initial state */& p, R$ Y0 K' a0 s4 |) i
  154. }
    2 @2 w- ~, T9 b/ n/ B

  155.   y$ r; U2 b! A5 [) }3 R$ {
  156. /************************************************************************/( g9 K+ D! b' w
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    8 o# h' ~0 c" C+ b' f; z# z
  158. /*                                                                                                                                                */
    1 x+ \& i1 C$ u$ b8 p
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */* z& K' i* v3 n) _, [6 k+ H
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    ) U, ~0 d# @3 A/ w
  161. /*                                                                                                                                                */7 y7 B' I/ f. P' Z& p- H
  162. /* Input:                                                                                                                                */9 B& x+ ^  Z; B- Z/ b+ i
  163. /*                out                                                                                                                                */3 m! E9 C- i; S4 X, ?4 U; I
  164. /*                                                                                                                                                */- m+ L; o6 |9 k0 d7 q9 H3 K( s# j
  165. /* Output:                                                                                                                                */
    4 Y) @: R6 K; ^
  166. /*                SI                                                                                                                                */0 k2 j  ^( O/ a2 u: H
  167. /************************************************************************/( p5 ]3 ]8 X, g! N& o
  168. void Send_Byte(unsigned char out): U; `1 J0 ~( W2 F# m0 {% }& D! S
  169. {3 D( C) l9 H. X* Q+ a4 H
  170.         $ v$ C, I4 |1 S! {* h9 ]3 g
  171.         unsigned char i = 0;
    9 H3 B3 O4 L/ u" h
  172.         for (i = 0; i < 8; i++)
    ! z/ W' L, a! x+ d" e
  173.         {
    $ r2 f0 f) P% b% }& ]0 A
  174.                   p5 \% B7 c- I/ z. K. ]  l& \) z
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */( `! a6 J& `7 D8 [$ u
  176.                         SI = 1;+ N5 E0 a; C% Y& a9 y1 ?* [
  177.                 else
    4 r/ J5 U( B$ I& y8 l/ }
  178.                         SI = 0;                                /* if not, set to low */
    $ N( B% m( |  q' B5 \
  179.                 SCK = 1;                                /* toggle clock high */
    ! Q/ A; |+ b5 H( B: f# P
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    ' ~3 P5 P' l, R( o% z: ?6 ~( J
  181.                 SCK = 0;                                /* toggle clock low */+ v& L( p( ]; J( \4 W
  182.         }2 |6 v1 W  R  p3 T* V
  183. }
    / C/ x6 y" J! M

  184. 0 C) ^! }* W& N$ v3 U0 V
  185. /************************************************************************/1 r2 {! _$ K0 O3 [* P
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    - ~" ^! Y4 B: u3 D* A, T# U/ O
  187. /*                                                                                                                                                */
    ) l9 u* f* K' T! @! u6 D
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    , d0 F( f; G: N6 F5 c% [
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    # b7 c5 u9 n3 [5 q; x, ?
  190. /*                                                                                                                                                */+ j# n. [+ P& k
  191. /* Input:                                                                                                                                */7 j3 Z" R) t% n2 J7 o' o$ l
  192. /*                SO                                                                                                                                */
    1 M8 x: G8 k* t" o1 a2 ]7 v
  193. /*                                                                                                                                                */
    ! t0 ?* y1 i9 a& {
  194. /* Output:                                                                                                                                */9 X3 `% Q3 t- s* U& A( N
  195. /*                None                                                                                                                        */
    # a" X: {/ [( w8 I
  196. /************************************************************************/" ]% [5 @" H  A$ F
  197. unsigned char Get_Byte()
    4 D4 m: T6 X0 H- @4 B
  198. {
    2 a- p* |+ G( h6 R& w5 c! M! F
  199.         unsigned char i = 0, in = 0, temp = 0;* j1 I6 i( C" _! j; Q
  200.         for (i = 0; i < 8; i++), Q2 i5 }- m, E
  201.         {
    + f( @, ?5 n4 z0 i) X+ Z( i
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    6 n; A  R. ?/ w7 h, u
  203.                 temp = SO;                        /* save input */
    2 J3 E8 k, g" o4 W6 a: O
  204.                 SCK = 1;                        /* toggle clock high */  z% C6 j- R. s7 W+ I. i! F; B
  205.                 if (temp == 1)                        /* check to see if bit is high */
    * `  C2 F  k, E8 f
  206.                         in = in | 0x01;                /* if high, make bit high */
    : h+ Y1 ~- U% @: q6 t6 C

  207. 0 s3 I! N7 _0 \% y) w8 e7 f7 ^  w
  208.                 SCK = 0;                        /* toggle clock low */, Y- }- |' R( Y
  209. ' \4 g4 ^& o- D8 B
  210.         }8 p& ?; ]) }& A* l: C& L" T2 x
  211.         return in;* `7 y% H8 x0 v  Y( q* s& z
  212. }# ^/ H; e# d' k2 B- d: E
  213. 0 f# V9 T  I) |" ?, u: |  B8 r
  214. /************************************************************************/( c" |* X3 S9 |
  215. /* PROCEDURE: Poll_SO                                                                                                        */# e' G% y8 h! `  a7 V+ u9 N0 S7 u2 {
  216. /*                                                                                                                                                */
    - e& K9 e, w8 V7 R$ E; M# n
  217. /* This procedure polls for the SO line during AAI programming                  */
    ) w+ U2 _! N+ K! z
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    # t2 X9 {% L% Z; }; V( ?
  219. /* is completed                                                                                                                        */
    9 U) p( ^6 T* }3 L: b+ ~* U
  220. /*                                                                                                                                                */
    $ `# v( Y' q$ W9 k4 l2 r* g
  221. /* Input:                                                                                                                                */; j7 r! C& o1 g1 a% i5 D0 S' k+ N
  222. /*                SO                                                                                                                                */, i! l: E  P. U
  223. /*                                                                                                                                                */
    4 k, }. g2 D  F6 o1 a) e8 I6 h3 g
  224. /* Output:                                                                                                                                */; h0 [5 R6 b' Y
  225. /*                None                                                                                                                        */: Y4 j- w1 T% K* W8 b. N
  226. /************************************************************************/
    6 \5 w# Z" T/ K
  227. void Poll_SO()( W+ B; P, s. ]2 H
  228. {# ~' E7 G$ L: c& |
  229.         unsigned char temp = 0;
    2 r( c' X  Q$ p6 y: x
  230.         CE_Low();
    * E; d  l# \& w$ A- {- B
  231.     while (temp == 0x00)        /* waste time until not busy */
    # Q# J; S/ q' P. r4 Y( n
  232.                 temp = SO;( k6 s+ X" ?+ l
  233.         CE_High();0 J- f' M' H5 q
  234. }/ h' p( i, o6 x+ s$ b# @6 S
  235. 6 T+ A1 Q4 v) u% v3 Q
  236. /************************************************************************/, {  ]: M8 F& A! v) B1 l. r! a! o
  237. /* PROCEDURE: CE_High                                                                                                        */9 ^) m( _- c: j& R. K# m
  238. /*                                                                                                                                                */
    6 S+ g$ |9 X; U) U. i6 q: ~0 H
  239. /* This procedure set CE = High.                                                                                */& j  ~, |  S7 Q/ S6 A( s
  240. /*                                                                                                                                                */$ o" P7 y0 J% m+ J& F2 l+ F2 `
  241. /* Input:                                                                                                                                */
    & N2 ?' v" ?# }
  242. /*                None                                                                                                                        */. i' Q$ H/ C- O" b0 m, j5 q  ?& \; N: K
  243. /*                                                                                                                                                */8 T) T9 u3 a) W& [
  244. /* Output:                                                                                                                                */
    $ L' h, |+ Z; w9 \# _3 |
  245. /*                CE                                                                                                                                */
    : I) t( |7 H0 H3 d& |; J2 T
  246. /*                                                                                                                                                */
    / V3 V: R6 e  V0 Y  N" `2 w1 }
  247. /************************************************************************// V9 V8 u; \7 P# j" X( p! m
  248. void CE_High() 3 Y; ?0 D% p9 Q0 e: c9 \0 Z. x
  249. {
    , h* J; S) w& t" t0 g; J% L2 n
  250.         CE = 1;                                /* set CE high */
    1 n/ J# D! ?4 d2 q2 f0 S
  251. }$ _# G' e; z8 _3 J  u& T) V; H, O- e

  252. ; n& s+ h) R$ D% O
  253. /************************************************************************/
    + {' w' ^; n+ o3 @% Y- S6 C  B! B% t
  254. /* PROCEDURE: CE_Low                                                                                                        */- s5 H+ f6 Y3 x! x9 q
  255. /*                                                                                                                                                */
    ! b9 Y2 ^: O5 Q: l, f) f  O$ z
  256. /* This procedure drives the CE of the device to low.                                          */
    1 i/ P, p+ K, S' b" y  v  k
  257. /*                                                                                                                                                */
    * e+ D' l, X2 b) U: |1 O
  258. /* Input:                                                                                                                                */( d" l5 h4 f: k" ?- F( M$ b( m
  259. /*                None                                                                                                                        */
    # }2 i4 ~( N2 R0 T0 I# I! o' Q
  260. /*                                                                                                                                                */
    ! g) f: D3 s2 q9 q7 H
  261. /* Output:                                                                                                                                */
    ( Y7 W- A( ?. r4 r4 H& n/ S
  262. /*                CE                                                                                                                                */
    : g' @0 a! {( f2 z, V/ D1 x# L- p
  263. /*                                                                                                                                                */
    ! ^2 B4 p. b  e. a) K( p; I
  264. /************************************************************************/
    ! H& R9 j: p! m3 S4 E( ~# ?' g6 G
  265. void CE_Low() 4 i4 D! R* d* B4 ?6 t2 q+ m( ~% d
  266. {        * i5 C+ C' S( e$ k* \
  267.         CE = 0;                                /* clear CE low */4 E5 n6 U$ b% k" u% V$ f( |. O
  268. }
    / |( d/ \) ?; H, ?

  269. ! d  ]3 i, A$ G. W. |
  270. /************************************************************************/' Z8 G! t* I5 R9 V
  271. /* PROCEDURE: Hold()                                                                                                        */  k, [; G3 h6 `! ^2 M
  272. /*                                                                                                                                                */
    & I7 k2 i: J" m8 `/ S; ^
  273. /* This procedure clears the Hold pin to low.                                                        */6 ]5 F7 K. k. E( s$ J9 e
  274. /*                                                                                                                                                */
    " O- z9 F! F" a" q! \. j
  275. /* Input:                                                                                                                                */$ u) G" S+ n1 X+ O  T
  276. /*                None                                                                                                                        */1 r9 B: u& k9 W3 ?4 y0 `& l7 p
  277. /*                                                                                                                                                */
    ' ?. q" a9 t( n9 b+ X- a3 ~. h1 q5 ^
  278. /* Output:                                                                                                                                */  Y! `6 z! l+ N: c
  279. /*                Hold                                                                                                                        */
      M1 m4 V8 g$ u( |3 q7 y2 b5 Q( ~
  280. /************************************************************************/
    8 _! @6 _) J  R4 d
  281. void Hold_Low()5 n$ s% D4 h' L8 P
  282. {( t' V7 x9 @% B& B' ?3 X
  283.         Hold = 0;                        /* clear Hold pin */
      v( l& n" J% j, l8 Z6 r
  284. }  s& J) W4 y" `

  285. ( b: H7 I; ~4 z" _1 K: E' h/ ?
  286. /************************************************************************/* R* f5 }8 Q. U1 ~( ]! z) |
  287. /* PROCEDURE: Unhold()                                                                                                        */
    ' }4 C) ^6 k$ d3 L
  288. /*                                                                                                                                                */
    5 r, ?/ S/ r  r
  289. /* This procedure sets the Hold pin to high.                                                        */
    % E5 l# S, ]& C2 _4 l2 s
  290. /*                                                                                                                                                */# J$ i6 Z) t6 J. @4 @9 E
  291. /* Input:                                                                                                                                */( w" e8 f# b; x9 k( b
  292. /*                None                                                                                                                        */7 E' C- B# Y+ g1 O! n
  293. /*                                                                                                                                                */
    " v- C# c; L9 M1 v4 B
  294. /* Output:                                                                                                                                */
    * H+ F$ R6 q5 E: k( ^+ i; H8 o
  295. /*                Hold                                                                                                                        */9 p; V2 s0 A! `7 G1 x
  296. /************************************************************************/
    5 |& d4 T# M+ i, Y% U- Q
  297. void Unhold()
    1 ~" ~  g' s+ n7 Y. S  E
  298. {
    2 G( L' ?) K* ~* j# H7 X
  299.         Hold = 1;                        /* set Hold pin */
    - `' q, }1 E; R  p
  300. }9 p& _% p; T+ m: k$ r

  301. 3 e% R; j+ q. R/ @
  302. /************************************************************************/* w& v6 `& D7 F% {+ d
  303. /* PROCEDURE: WP()                                                                                                                */
    % t4 C$ D! P9 u" q, N' s" H4 H
  304. /*                                                                                                                                                */
    7 I5 X6 r: A( V, \& u) [6 I; E
  305. /* This procedure clears the WP pin to low.                                                                */
    : C7 c& i" [" r- G% f9 n
  306. /*                                                                                                                                                */
    9 S8 @4 l7 P5 {, L3 l* S
  307. /* Input:                                                                                                                                */* I2 ]5 a9 i5 M
  308. /*                None                                                                                                                        */" ?5 k5 M8 j& ?+ A+ Y  \  z
  309. /*                                                                                                                                                */% }* f4 i7 T3 }" ]9 W9 q
  310. /* Output:                                                                                                                                */
    % p' [1 }% y1 x/ R4 p/ K+ O
  311. /*                WP                                                                                                                                */' v% U, [) {, R: u/ H, V/ J
  312. /************************************************************************/
    % h8 j* e: p% p- |$ E/ }
  313. void WP_Low(): ?) k4 m8 x  S/ l* u
  314. {/ E/ f' [+ u  i
  315.         WP = 0;                                /* clear WP pin */
    0 i- z2 y) ?- q& M1 j
  316. }
    - l5 L4 f! ~* D& {1 O) J

  317. 2 J% b" M5 k/ Y5 Y  T/ Y
  318. /************************************************************************/
    " Q% a, B- r' D3 M
  319. /* PROCEDURE: UnWP()                                                                                                        */- Y' Q4 E/ d7 V% {% X3 X  {& F. ^) o
  320. /*                                                                                                                                                */
    , ~3 Q; g- O, q0 Z
  321. /* This procedure sets the WP pin to high.                                                                */
    * b+ @7 Q% J" @% Q; g( x" |
  322. /*                                                                                                                                                */
    7 H$ d* @3 e! {3 S/ r) v% t, I
  323. /* Input:                                                                                                                                */. u) `1 f$ a, z4 ]5 g9 ~
  324. /*                None                                                                                                                        */
    5 {( I9 u# j1 x  f$ s8 U
  325. /*                                                                                                                                                */# Y6 R  ~4 o$ k/ D# Z. t
  326. /* Output:                                                                                                                                */
    9 {5 d9 ?3 v9 s- }- u* W# Y
  327. /*                WP                                                                                                                                */
    : \, u& e) B/ A& w& M( F
  328. /************************************************************************/5 @, z% Y3 W/ m/ w; [
  329. void UnWP()8 i& B3 V4 ^3 y  U2 q$ M9 u4 f) f$ T
  330. {
    & E% J0 {' ]" `) C6 `+ q+ F* v' L
  331.         WP = 1;                                /* set WP pin */
    7 w. ]" W4 a" v- f4 i8 U
  332. }. ~  w/ W7 Q# B( o2 A

  333. ' _" r5 G. s1 V
  334. /************************************************************************/1 ]( H; o8 f* u; T" [
  335. /* PROCEDURE: Read_Status_Register                                                                                */2 c3 G! Z$ u/ B) [
  336. /*                                                                                                                                                */+ j2 A6 Y# e6 `1 P' L  K
  337. /* This procedure read the status register and returns the byte.                */  t4 L3 i" C: {. J
  338. /*                                                                                                                                                */9 L/ n; \1 N* U
  339. /* Input:                                                                                                                                */1 S& j5 D- u& b# x
  340. /*                None                                                                                                                        */+ D2 u8 w  [* X& |
  341. /*                                                                                                                                                */( h. G- Q% @' l+ w
  342. /* Returns:                                                                                                                                */9 r4 E9 {" [) W' I+ V
  343. /*                byte                                                                                                                        */
    ! z, Y- |/ x9 b* o) |
  344. /************************************************************************/  b) F! X: T9 }3 d9 }5 j2 q
  345. unsigned char Read_Status_Register()
    7 k  B' F2 F3 M0 |) A
  346. {0 H' i' i9 s1 T5 `1 V- F- j
  347.         unsigned char byte = 0;) N  o- }+ u$ M6 }% m8 _
  348.         CE_Low();                                /* enable device */; w& G( K' _/ n' z
  349.         Send_Byte(0x05);                /* send RDSR command */
    # U* h) h2 q2 D
  350.         byte = Get_Byte();                /* receive byte */' m6 y* i( |4 W0 v4 p
  351.         CE_High();                                /* disable device */
    " I. \0 X; t% k% }6 T
  352.         return byte;
    ' o$ U3 U" x! q
  353. }
    . W4 ^, ^  G1 O5 U6 x; T! f

  354. 5 R! i$ [; \  [2 n
  355. /************************************************************************/7 `0 S# w+ Q( P, v/ V) C
  356. /* PROCEDURE: EWSR                                                                                                                *// m" O# k5 _2 Z' s* n/ ~
  357. /*                                                                                                                                                */
    6 u+ v! Q7 `1 X2 c
  358. /* This procedure Enables Write Status Register.                                                  */$ v) h! V( ]4 u; |' k4 d7 f
  359. /*                                                                                                                                                */
    . p3 J5 Q. J" X6 s7 B' x
  360. /* Input:                                                                                                                                */4 Z' B8 f& b6 q' f( {
  361. /*                None                                                                                                                        */
    . w& z1 H7 |- U* B( {# o/ ~
  362. /*                                                                                                                                                */
    : p0 v  |& O8 h* ~% }
  363. /* Returns:                                                                                                                                */, q  J/ q7 C0 n
  364. /*                Nothing                                                                                                                        */7 A& r6 a' H1 s  u9 v2 ]
  365. /************************************************************************/
    8 R' V' M: L6 u$ J& P
  366. void EWSR()
    * T' P: E6 k2 s2 {
  367. {
    " t* b5 r# U4 M+ g
  368.         CE_Low();                                /* enable device */
    & Q; ]; P7 j0 A5 ]/ W. h
  369.         Send_Byte(0x50);                /* enable writing to the status register */+ `+ X3 f  d, @! [- D. B5 p4 W
  370.         CE_High();                                /* disable device */* W" R( _! u8 E
  371. }
    / I; E9 \8 ?  `5 ]

  372. , ?+ }8 C3 p9 X: ~
  373. /************************************************************************/
    % S, K5 q: l6 e2 R6 J4 [6 x
  374. /* PROCEDURE: WRSR                                                                                                                */
    ' X3 O! p4 C: q/ o  l, j. l  }0 s3 f
  375. /*                                                                                                                                                */% U# t9 W# B, i5 V+ K6 i3 ~; [. G6 n0 T
  376. /* This procedure writes a byte to the Status Register.                                        */. T  F8 A+ @4 e1 z: W7 O# B
  377. /*                                                                                                                                                */
    ) c3 R4 r7 ?) F  D
  378. /* Input:                                                                                                                                */
    # r9 j; Q3 W9 d5 w
  379. /*                byte                                                                                                                        */
    2 o2 B& N  O8 X- N) C
  380. /*                                                                                                                                                */
    * O- e, `0 R9 \
  381. /* Returns:                                                                                                                                */* d6 N$ L8 I" Z" Z: i# U
  382. /*                Nothing                                                                                                                        */& @7 D) }- _" K/ m/ s
  383. /************************************************************************/: u% I1 j6 }# [; Z1 q7 W
  384. void WRSR(byte)
    ( F5 h9 @" \& f: q. `
  385. {
    ) r+ G* Y0 y  u; h7 {
  386.         CE_Low();                                /* enable device */
    * E  n) e# g0 p, \, u
  387.         Send_Byte(0x01);                /* select write to status register */
    " L# f6 A- C. c- e7 }
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    # ?* ^+ @% N% j# P
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */( N' i( f5 r5 v3 i
  390.         CE_High();                                /* disable the device */
    + e- N& W9 T, r# I, K
  391. }
    : p9 M6 }. Y: e+ B/ ]

  392. 7 \  F4 z& B8 Z: u0 `8 ?% V
  393. /************************************************************************/
    ( }' L4 g; t# s0 n6 f9 R
  394. /* PROCEDURE: WREN                                                                                                                */9 H9 v* C/ |  s8 ^8 x4 Q: {
  395. /*                                                                                                                                                */
    1 N* ?+ v# u8 M* e# [+ [$ T
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    ) ~: R4 d6 d2 i, j5 s# P
  397. /* to Enables Write Status Register.                                                                        */$ i  a8 j4 x* g5 ]2 D) L% k
  398. /*                                                                                                                                                */( r" x1 H" g3 X7 o  u; w
  399. /* Input:                                                                                                                                */! ?4 c' Y& v4 J0 j, Z* v
  400. /*                None                                                                                                                        */* Z  K6 U& o0 k. X2 R
  401. /*                                                                                                                                                */4 N" Q  f  ?* E- W6 Q
  402. /* Returns:                                                                                                                                */- Z: A9 N, s0 p% q' {1 r% ]
  403. /*                Nothing                                                                                                                        */. ^$ E2 U5 k# E* v3 h" B
  404. /************************************************************************/4 Q* n& j9 m6 m& F' C1 O, A; o
  405. void WREN()
    2 I- r0 Z# R( o8 H. r" o
  406. {6 x6 s. `  C2 @$ c0 s# Q
  407.         CE_Low();                                /* enable device */$ r+ U+ q7 S/ Z- U  o
  408.         Send_Byte(0x06);                /* send WREN command */9 |) p- K. y8 L2 C' D
  409.         CE_High();                                /* disable device */* A/ v, K+ d/ d& Q; a- ^
  410. }6 q; q7 t- K5 s
  411. 8 Z& c, i& ^! M9 O  c. H
  412. /************************************************************************/( A+ [% l( a, i+ w. B! j
  413. /* PROCEDURE: WRDI                                                                                                                */+ h7 Y( B2 L) z
  414. /*                                                                                                                                                */, J7 \' ?: y9 @% Y
  415. /* This procedure disables the Write Enable Latch.                                                */
    : H5 M4 Y# g, k# I4 e
  416. /*                                                                                                                                                */$ T/ B; ]" i" e8 d  i- G9 J9 @
  417. /* Input:                                                                                                                                */
    + W. Z6 L* C5 ?" I5 q( D
  418. /*                None                                                                                                                        */
    ! K1 f. |; I0 G7 |
  419. /*                                                                                                                                                */
    5 \3 P* o" e& C- r7 c( [, p
  420. /* Returns:                                                                                                                                */6 w5 _& s* h1 N3 s1 _
  421. /*                Nothing                                                                                                                        */
    & G" f0 D% D. z4 k
  422. /************************************************************************/
    % V. v/ _6 @$ q+ X, i; Y" {
  423. void WRDI()( x9 n8 u& ]  }
  424. {  s/ Z( I" O3 a$ i
  425.         CE_Low();                                /* enable device */
    4 p5 j+ Z7 t2 G. [
  426.         Send_Byte(0x04);                /* send WRDI command */
    * _/ f6 M# [" y( D5 F9 G! |
  427.         CE_High();                                /* disable device */
    ( ^* s3 r6 u5 E  I
  428. }' [" Z  _4 ?  g  A6 j) F

  429. 5 N+ X) R6 |& e3 o# s
  430. /************************************************************************/
    1 N$ u3 T( a. a. ]2 Z- w  m: h
  431. /* PROCEDURE: EBSY                                                                                                                */; t1 y" i) Q/ i4 @0 b0 l
  432. /*                                                                                                                                                */( Y9 I$ w8 y8 y7 L" y
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    6 ~9 \1 f+ |9 x7 d* c, h
  434. /* programming.                                                                                                                        */* m) Q7 G% m0 H* y
  435. /*                                                                                                                                                */
    , `& S1 K2 Q! E% @4 G$ K
  436. /* Input:                                                                                                                                */& o& M0 B2 Z( _6 T, v
  437. /*                None                                                                                                                        */  y: u3 n7 j  M  h
  438. /*                                                                                                                                                */( c: i+ ]  L' r1 A9 o" X
  439. /* Returns:                                                                                                                                */
    ) D. L, D4 n; o: O- i
  440. /*                Nothing                                                                                                                        */
    & K3 A4 ^* ]8 {
  441. /************************************************************************/
    7 a8 H! ^" I2 r1 V) X3 R+ N8 N
  442. void EBSY()
    $ t; |! W- q1 I9 ?! h
  443. {
    ; J9 e2 N, y  K5 `( r  Z" K0 S
  444.         CE_Low();                                /* enable device */
    2 I9 Q: o; Z% q9 m6 F) e
  445.         Send_Byte(0x70);                /* send EBSY command */
    7 S% B3 ^, A. m0 t' V1 z5 {
  446.         CE_High();                                /* disable device */
    - }* s' e  t% ^* W! F, l
  447. }
    6 m# v4 a7 w  @- {1 \( z! g
  448. 4 i% `! ^1 O- Q2 I; d" o! R$ [( G) q
  449. /************************************************************************/
    0 k: i7 S7 M" x
  450. /* PROCEDURE: DBSY                                                                                                                */
    4 M9 J7 g, \( c
  451. /*                                                                                                                                                */1 o$ s6 t! r3 d/ \1 Q3 D
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */" O' P0 S+ u* h
  453. /* programming.                                                                                                                        */0 _* z8 r+ V3 _/ Q! a
  454. /*                                                                                                                                                */
    0 d* F6 d& w( A  r; I" o
  455. /* Input:                                                                                                                                */% s0 K9 M7 V8 _
  456. /*                None                                                                                                                        */
    5 }& A; E7 H$ C" _; j( [/ M
  457. /*                                                                                                                                                */
    " p: q# W& J) x3 m" K! d- p
  458. /* Returns:                                                                                                                                */
    , K2 Y  j9 [: `- h! P& @! M
  459. /*                Nothing                                                                                                                        */9 l5 }# z6 \* u$ }" i5 n; p: Q
  460. /************************************************************************/' @4 i$ N$ C+ Y1 t& z( j' y/ [
  461. void DBSY()
    : C! S$ _* x* [3 ]! @/ Y* T' K0 n
  462. {
    : [' w5 |) {4 U( P% ^: x
  463.         CE_Low();                                /* enable device */* T9 \; |' M; g
  464.         Send_Byte(0x80);                /* send DBSY command */! A: X2 k, P1 _% k) ^+ G5 n, N
  465.         CE_High();                                /* disable device */; ^* e! l9 T+ P7 w! v$ Q
  466. }8 P, L. l& P3 Q6 f5 [: O

  467. * s4 W, H0 B9 T* K. \) m  F5 _& r
  468. /************************************************************************/2 l3 \" \* @( ~; }( R3 k
  469. /* PROCEDURE: Read_ID                                                                                                        */
    ) i: E. M% p8 }" s* g
  470. /*                                                                                                                                                */
    8 P4 N- H0 p( h2 z9 b
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */% H* m: z' L; y, y2 g
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    " E' O- @0 U. @; p
  473. /* It is up to the user to give the last byte ID_addr to determine      */# N; ^9 D( j& d% G" A( [. ?: ]
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    0 C, ~5 c! I$ r3 N
  475. /* first.  Please see the product datasheet for details.  Returns ID in */4 j2 Q( o+ A( N% j; [- H# v" }
  476. /* variable byte.                                                                                                                */
    8 B0 ?" m# P4 T3 r$ L5 r
  477. /*                                                                                                                                                */+ k; O$ Q& c3 K5 g7 N
  478. /* Input:                                                                                                                                */
    ' P; X) |4 [  u
  479. /*                ID_addr                                                                                                                        */0 r3 I6 P* P1 Y  L
  480. /*                                                                                                                                                */
    2 G' k" k6 g7 `/ d! B' U0 j
  481. /* Returns:                                                                                                                                */$ ~/ K/ C" n' h
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */3 a& x/ R: t0 _0 d, ?4 f
  483. /*                                                                                                                                                */
    1 o" D5 S4 X* ~. O+ E" u/ T
  484. /************************************************************************/3 [: A8 e! @& b9 f- [
  485. unsigned char Read_ID(ID_addr)1 ]9 }" O. V9 a/ u3 k0 U
  486. {
    9 t0 {/ |0 h: f0 I; X! N
  487.         unsigned char byte;4 [' I* v/ h7 x. _$ t) x6 \
  488.         CE_Low();                                /* enable device */
    0 X" O" h' m8 L5 V
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    # x6 k9 q; r+ t1 ~% v/ D' K
  490.     Send_Byte(0x00);                /* send address */
    , @, Z/ q7 n" }
  491.         Send_Byte(0x00);                /* send address */
    : n& O% Z, M& B' i7 ]8 j
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */  ~3 H0 h% m7 k9 B( n7 N
  493.         byte = Get_Byte();                /* receive byte */8 I% s" C& [& `/ k2 ]
  494.         CE_High();                                /* disable device */
      G1 q! e% m3 T( Q( l2 g* ?
  495.         return byte;$ o8 R' c* Z% H6 ~/ |
  496. }
    - l2 O  Y  H4 O. [) }1 Y+ B: E
  497. 2 T. h7 ^% ~6 @% k8 Z8 H
  498. /************************************************************************/
    1 u: P" b/ |# P! |
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    . V$ r- N' I% _+ \. x+ J, U3 u% L
  500. /*                                                                                                                                                */" @% m: j+ e8 J' q  E4 w
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */4 O! [' z4 x( Q8 k
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    3 ^0 `& j1 M: O+ @5 n
  503. /* Please see the product datasheet for details.                                                  */
    $ M1 P& Y9 ]5 U- b
  504. /*                                                                                                                                                */! m% ]0 S7 m: j8 d1 o
  505. /* Input:                                                                                                                                */
    4 J, w- n7 M" L$ ?( w  F; e
  506. /*                None                                                                                                                        */
    . i) l# z7 m) Y1 T' y
  507. /*                                                                                                                                                */5 Q& |7 t$ n- E. z( ~, P9 A4 x
  508. /* Returns:                                                                                                                                *// T" f6 m/ s0 i0 v5 I/ M' s
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    4 K2 e! Q/ l1 w" h2 y: g
  510. /*                 and Device ID (8Eh)                                                                                        */
    + }% [# A' B" R7 Y6 i: |7 |* l- J. c
  511. /*                                                                                                                                                */& S+ {! m: n# {$ w6 \
  512. /************************************************************************/) t, ?/ c; f6 x* B4 g. a* o$ E
  513. unsigned long Jedec_ID_Read() ( @( O/ C' }/ H2 }3 p  o1 a
  514. {
    0 t+ \& x8 m+ `+ L" T& ^
  515.         unsigned long temp;5 q( m! n5 C7 {) p
  516.         " t: {8 S$ ]6 h- Z: R
  517.         temp = 0;
    ' ^, d. D* r+ n7 R9 H: m

  518. ' w( i3 z% i; \" ?3 N' O( @
  519.         CE_Low();                                        /* enable device */" S# Y+ o, C7 k' |+ f6 g3 t
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */6 O! j- O8 r8 G) H5 k
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    4 N9 v" q  C' x$ G9 G$ o4 u+ D/ P
  522.         temp = (temp | Get_Byte()) << 8;       
    * F4 _0 [' X$ |, n/ U  J
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */3 @8 w# X$ d5 |7 e! y6 P
  524.         CE_High();                                                        /* disable device */
    ! I; i6 h& M2 n% Q
  525. / n4 }) `, [1 {
  526.         return temp;; Z; h. \$ r, B+ {8 Z, c4 T
  527. }
    8 ?, v5 c' W# q6 J6 y" [: s

  528. ' v% J  A6 @. _% B4 W( b
  529. /************************************************************************/
    $ c# _3 L" w/ X4 @+ ~
  530. /* PROCEDURE:        Read                                                                                                        */
    7 e/ b: _) q: ?* O
  531. /*                                                                                                                                                */                & {$ D& f' y3 ?) ?* v$ x! h
  532. /* This procedure reads one address of the device.  It will return the         */
    . p) s  s0 r( o8 P9 g
  533. /* byte read in variable byte.                                                                                        */
    % `+ f' d4 l; \
  534. /*                                                                                                                                                */1 W# m3 z; T* \! j; _( a0 B6 y6 o
  535. /*                                                                                                                                                */% a' @6 y- t9 x
  536. /*                                                                                                                                                */# _! [# Q+ a# J
  537. /* Input:                                                                                                                                */
    5 O8 B  ]$ {$ C1 q9 u
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */& B# S! ?4 K7 Q$ [: t3 \
  539. /*                                                                                                                                      */
    7 t3 Y7 P; f! [4 f& S/ O
  540. /*                                                                                                                                                */
    * T( Q/ b4 G  A' r
  541. /* Returns:                                                                                                                                */9 H, Q, W1 A  c  v8 \/ `
  542. /*                byte                                                                                                                        */
    ' V* A4 M) `  y& m3 O, x2 S3 L
  543. /*                                                                                                                                                */
    ( Q+ e7 N, i. q# }! g; f: p
  544. /************************************************************************/" r8 J/ J' [$ z3 G# r
  545. unsigned char Read(unsigned long Dst)
    ) t  L+ M* \1 t+ A/ n/ i$ |2 f
  546. {
    - U0 n! ~( c* N& @" Z* r# I
  547.         unsigned char byte = 0;       
    : `6 q9 E% D& ^, c/ ]4 `9 j( R

  548. 4 }( A/ z6 T, {6 \# e( d. O8 L( I
  549.         CE_Low();                                /* enable device */
    / o2 T. h2 I+ n6 j# o4 d9 \
  550.         Send_Byte(0x03);                 /* read command */6 V- M, f9 B# s+ d
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    , [; i& }/ L) l5 D
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 b+ _6 A( K, S
  553.         Send_Byte(Dst & 0xFF);3 @- d1 H: J; S8 C5 C5 m8 K
  554.         byte = Get_Byte();" E0 ^) y- Z- z/ T+ z. U
  555.         CE_High();                                /* disable device */4 T# q+ R! S% _, H6 b/ u
  556.         return byte;                        /* return one byte read */
    # [' e1 Q, i/ y3 m% p  a( m, V
  557. }% l& F+ U$ ~: K* M7 Z9 b
  558. * Z  K4 ~; B. O
  559. /************************************************************************/
    4 a2 R, T  U2 ]& l: x# Z# Y8 k- L) W9 L
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    / i; T- l( v$ {5 v; [
  561. /*                                                                                                                                                */                4 c0 Z4 o7 z) i/ G' z" b% P& t6 J$ I/ O
  562. /* This procedure reads multiple addresses of the device and stores                */
      H: s/ d9 G! N, X5 V: U
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    ! b* p0 @+ q- ?9 L% }
  564. /*                                                                                                                                                */" _8 l: `# t: f* T# Y9 v( A
  565. /* Input:                                                                                                                                */! A% j5 \$ \0 Q" J9 f" W
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & Q0 t6 N' W6 q! i  f
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */) N, b" ~; N. M9 k, Q4 g4 l
  568. /*                                                                                                                                                */
    1 Q0 F' L* s* m1 v! s
  569. /* Returns:                                                                                                                                */2 `' J, ]+ }' Q8 F
  570. /*                Nothing                                                                                                                        */# c# a) o  k7 n9 r$ L
  571. /*                                                                                                                                                */
    * v( f: z* f# O. I+ J: x
  572. /************************************************************************/! ]8 N  \+ X0 s' V- a5 h
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    . s+ o: A$ e  \" |6 A9 ~; z
  574. {
    ' M1 R$ l% [* N* m' B- @
  575.         unsigned long i = 0;
    9 D: n1 @% W, C( F+ ^8 X8 `
  576.         CE_Low();                                        /* enable device */1 k' V) I: Z5 s% o7 w
  577.         Send_Byte(0x03);                         /* read command */
    ; g1 q: f9 O- \- U' M$ O
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    7 L- `- }% C; U0 a/ j3 ]% u/ l3 w
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));% \# u3 D. A3 A
  580.         Send_Byte(Dst & 0xFF);
    ' J7 |+ q) Y0 p1 s# A* d
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    . \9 `* z" \% N  B' K
  582.         {
    0 x  Q: v7 A. X
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    : P3 V* U  W1 q' Q- d, x* ]! {
  584.         }. ~9 S: ?  W, O1 M
  585.         CE_High();                                        /* disable device */3 u( Q# `7 K* n2 d; w
  586. , }' w" Q9 \7 W- q# D1 N
  587. }4 o2 |/ a0 R$ X  X

  588. ' g: R$ R( N% D( z
  589. /************************************************************************/, t6 [# [7 B4 g# V/ }
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */. e7 G$ x; g. G. y5 P8 J% H1 ]
  591. /*                                                                                                                                                */               
    ' Q4 R7 V8 C! V! Z
  592. /* This procedure reads one address of the device.  It will return the         */
    : B% r/ R; d  O. o2 ?1 l# Y
  593. /* byte read in variable byte.                                                                                        */. I6 j* b. e8 O( j) h% y# L  Q$ g" x
  594. /*                                                                                                                                                */
    ; P  b( Y! B! y
  595. /*                                                                                                                                                */$ X' S$ Z$ u# V" X4 F
  596. /*                                                                                                                                                */. V: ^! W2 d2 c, J# J
  597. /* Input:                                                                                                                                */
    7 \3 b" P5 e+ w3 b9 b- M9 `
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */: l# ~/ g: _3 y, ~2 s; n
  599. /*                                                                                                                                      */
    3 |3 ?1 M! h* x( [
  600. /*                                                                                                                                                */
    3 U% K8 R5 g7 e4 ^* C' e5 q
  601. /* Returns:                                                                                                                                */
    , N8 }! d( B' b+ h
  602. /*                byte                                                                                                                        */
    : b1 Q7 B) X/ M. b
  603. /*                                                                                                                                                */
    & ?+ ^% R2 a9 \' D( u$ X1 C' o
  604. /************************************************************************/4 W, ]$ \0 Y4 I/ ]
  605. unsigned char HighSpeed_Read(unsigned long Dst) : L2 Z/ j  M) U+ L0 g5 H% \7 X1 n
  606. {
    & g: x: F3 {" M( r
  607.         unsigned char byte = 0;        ) T: g! r0 y6 x3 n9 y0 a8 _$ T
  608. 3 M, V0 d. U' q+ z- d7 Q2 h3 X3 U
  609.         CE_Low();                                /* enable device */) ]7 O7 U5 g6 ^2 u
  610.         Send_Byte(0x0B);                 /* read command */. k2 B$ w2 g  o4 h; S
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    * s1 \4 A4 J6 Q1 M# d3 D$ |& ?/ [
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 l+ |' p; Y% ]( B) H2 [
  613.         Send_Byte(Dst & 0xFF);8 v; j7 Z" C" F: s: L0 D
  614.         Send_Byte(0xFF);                /*dummy byte*/
    " N$ P8 u1 P4 z' h
  615.         byte = Get_Byte();
    ( L" z0 L( D/ Q. ?2 m
  616.         CE_High();                                /* disable device */
    & j& @& c% P' O9 b8 s8 E3 T
  617.         return byte;                        /* return one byte read */
    & g  [, I# i! J: v$ l( a
  618. }# @" C) ~  R- y2 J* W

  619. 3 e/ f5 v% c% z" `+ Q( b! U
  620. /************************************************************************/
    5 }6 r7 E0 y6 A& r( E( w( Y) M3 O# v
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */! }3 {# }9 ~3 T/ Q- A/ ^
  622. /*                                                                                                                                                */               
    9 P4 G9 M# n) V% _1 z
  623. /* This procedure reads multiple addresses of the device and stores                */* f! h( }4 Z# }0 s$ g
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    3 }% d6 M; b0 `' A1 x
  625. /*                                                                                                                                                */
    ' V4 W7 i1 K: f: [7 w2 u$ }0 ]( Y# @
  626. /* Input:                                                                                                                                */
    ( \! K/ L$ l& _$ B2 M. o
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    3 i* V9 Z! G' p% H% B( T( t$ Q4 ?* u: G
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    8 W( R: N  B! G  P% Y1 T, p
  629. /*                                                                                                                                                */: p3 n7 l+ s1 {, G4 x) @
  630. /* Returns:                                                                                                                                */
    ; a0 a8 y7 k* ]0 t9 Q5 ]
  631. /*                Nothing                                                                                                                        */
    3 m- B; K" W2 d0 `. ^
  632. /*                                                                                                                                                */- C% F9 z3 Z, s
  633. /************************************************************************/. n5 d. y' @% o7 q) v, n: z
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    " |8 M8 s5 M. X* B( V# j: u
  635. {6 m( [% ]$ Y( ]  y: K( L& s
  636.         unsigned long i = 0;
    2 R! r7 _( K9 w1 t
  637.         CE_Low();                                        /* enable device */
    + x' E: T& d+ E! F- {% O5 P' ~6 e
  638.         Send_Byte(0x0B);                         /* read command */
    * e9 W  \$ Z, L0 x$ R
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    . ?5 ]5 h+ y$ ~" u
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
      e5 u! m% o* M0 h8 t# f
  641.         Send_Byte(Dst & 0xFF);5 V' G/ q6 C: h! ?7 S- `
  642.         Send_Byte(0xFF);                        /*dummy byte*/1 O) D+ `. w! {1 y- ]
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */& m3 Y* M+ F% s' J- N
  644.         {) R! L0 E  G  K  J6 Y0 h+ c/ Q
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */* `0 n" o& I$ N
  646.         }+ q9 m# _' N, p  W
  647.         CE_High();                                /* disable device */
    : K7 c* b" Y1 w/ ~0 f% \# n
  648. }
    - h9 d+ o, J+ O6 C

  649. ) h: @, E5 ~. S- j0 M
  650. /************************************************************************/' d6 b& G( O6 i) }' f5 D5 V" E7 c1 s
  651. /* PROCEDURE:        Byte_Program                                                                                        */+ p# w, ~7 Q+ _; k3 j0 T
  652. /*                                                                                                                                                */
    " @; X, h& r& l( R* i
  653. /* This procedure programs one address of the device.                                        */
    5 t# C" T/ W$ g/ f1 p4 z+ S& X
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    & Z& i( q' k$ P9 U+ n5 s' }& F3 o
  655. /* block protected.                                                                                                                */
    & }# A' D, u) d) q/ O  s& ]6 o) O, E# N4 O
  656. /*                                                                                                                                                */
    $ ?# k. Z" s& G' o- [3 }
  657. /*                                                                                                                                                */
    - e$ [* ]: ]* @2 C4 I" t. _, q" v
  658. /*                                                                                                                                                */( n$ s- }/ ]$ s6 v5 T6 V( B% q2 L6 U
  659. /* Input:                                                                                                                                */. k" |  \( v1 D' B2 k, q0 m
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */3 ~" S* D% z; `0 g; P) N
  661. /*                byte:                byte to be programmed                                                                */
    3 O' _: j  H6 l9 c9 B1 n6 N8 z
  662. /*                                                                                                                                      */' p2 K2 H5 P3 M6 ~% B2 h* _* m
  663. /*                                                                                                                                                */5 n+ P5 O, W6 q% O5 b( f
  664. /* Returns:                                                                                                                                */
    * B0 X4 L3 u+ |) q" |8 U  D
  665. /*                Nothing                                                                                                                        */& \/ m  E+ o% L% I
  666. /*                                                                                                                                                */
    ) O+ r# q1 r/ o0 f( l0 U/ m2 [
  667. /************************************************************************/
    5 \4 n, ^$ Q8 |7 _+ w! i
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    ) x# o& y( a  U6 e$ f8 T
  669. {5 U" H, |( t& g9 u7 U$ ~9 w, \
  670.         CE_Low();                                        /* enable device */8 ~* u6 ^' a. z% V1 M* p
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    4 F) M( c9 @+ I- i" f
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    5 v1 T/ T  m6 o# W( `% f7 Y% b
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));3 ~& y4 }1 f: c0 X" O4 j- t
  674.         Send_Byte(Dst & 0xFF);
    3 \6 p& S" p/ T" q6 E
  675.         Send_Byte(byte);                        /* send byte to be programmed */0 q# V0 ?6 J! K; v% L( n/ _
  676.         CE_High();                                        /* disable device */0 C) Q+ @3 f$ c
  677. }; s2 v* U6 r" Q7 j8 {& A6 t
  678. 5 @+ V8 a7 D& Z% H; o
  679. /************************************************************************/
    + U* P) H( e, {! P- {- l
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    6 R2 Y, }$ i! `% w8 q- o3 i4 k
  681. /*                                                                                                                                                */
    / |- A1 u5 \8 ?' K  }
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/5 F; E4 H+ ^8 A% h2 R9 k1 f
  683. /* the device:  1st data byte will be programmed into the initial                 */$ G' X# u! q# B. {* x
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */" ?; f" o1 o/ T& c2 ^
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    7 e% O- z, C/ B% Z$ y+ v
  686. /* is used to to start the AAI process.  It should be followed by                 */
    7 E9 N8 i% y0 y. p, n* m9 G4 c7 m+ p9 o
  687. /* Auto_Add_IncB.                                                                                                                */
    ! c" g  U7 R# {9 l
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    - {4 k3 t, J3 D
  689. /*                                block protected.                                                                                */
    : K" A' r5 O# O5 u- I! [% p
  690. /*                                                                                                                                                */
    4 P5 j5 A. y$ P! M6 P
  691. /*                                                                                                                                                */
    # c( h3 q8 `$ _' p. g
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */: M" A: |" \& s' J) P
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */; w2 u( h5 q3 R9 ]2 k
  694. /*         unless AAI is programming the last address or last address of                */
    & [( {/ Y8 e) x
  695. /*          unprotected block, which automatically exits AAI mode.                                */5 L8 i8 j4 C: _/ j9 G/ }, {  }
  696. /*                                                                                                                                                */
    ! j: a0 B3 y9 N4 \: b4 s0 Z; x9 Z
  697. /* Input:                                                                                                                                */
    , U# s9 ^  Y4 v; g- t  b/ q6 m
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    5 J4 n2 z2 d. U! r* c% Z- l
  699. /*                byte1:                1st byte to be programmed                                                        */
    % x) L0 s0 h4 K. J
  700. /*      byte1:                2nd byte to be programmed                                                        */
    # q, v, u, {' q2 _7 N
  701. /*                                                                                                                                                */. D- p2 K0 K0 G: F6 D* ?
  702. /* Returns:                                                                                                                                */
    4 Z+ W$ [6 q# Z* |4 l7 v
  703. /*                Nothing                                                                                                                        */7 `3 _, i9 P) j9 I
  704. /*                                                                                                                                                */
    8 v4 Y0 A' s0 e5 ]
  705. /************************************************************************/2 |( Z, R% X' }0 ?* t$ o! w7 S
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)% r6 V0 a! j7 ^
  707. {
    * H7 G' R3 c  w
  708.         CE_Low();                                        /* enable device */2 X# F1 r- N$ R2 F1 |
  709.         Send_Byte(0xAD);                        /* send AAI command */- Q2 S2 g: a+ R5 I# l0 D4 R6 Q/ I
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ) \4 v% o+ b  K% m
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    0 [1 H1 y6 H0 X* s# a# n2 Y
  712.         Send_Byte(Dst & 0xFF);  f- ]7 ]2 G+ U! G( @9 Y
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    * @1 p  ~5 u0 b; Y$ k
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */- U" j: g- x! ~
  715.         CE_High();                                        /* disable device */) `/ Q6 M  b! {# H7 D
  716. }- X8 W' H. Z& I7 z6 c7 L* W

  717. 1 {' |) D' x4 K! v6 K1 r; R/ y
  718. /************************************************************************/: W1 l9 M4 R3 s& o4 A0 X  N# u2 U
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    + g# M: W* z' H
  720. /*                                                                                                                                                */: I4 ]; z6 U% \) a
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/5 @% b0 q0 h  c  y
  722. /* the device:  1st data byte will be programmed into the initial                 */
    * P& _5 ?) W7 J, j/ O* s
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */$ Y: Y& b% \8 C) ^/ y! b
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */* }4 [7 o5 ]+ W) h& w
  725. /* is used after Auto_Address_IncA.                                                                                */
    ! Z) @3 g/ o5 I7 d
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    ! |3 j5 r% V9 J& z
  727. /*                                block protected.                                                                                */7 M6 n2 }; O1 V1 n
  728. /*                                                                                                                                                */
      v  X, o: n2 V' b3 i6 M3 R( O
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    / y& y% ^* x. c3 P
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    ; R, e- p! Q( s7 X6 S" T, S7 F5 _7 n4 K
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */# J8 [: a! E- q7 B
  732. /*          to exit AAI mode unless AAI is programming the last address or                */5 E# z' H3 |% c: b  w- e7 q
  733. /*         last address of unprotected block, which automatically exits                 */0 p% K9 t3 v/ K& }2 ]) D
  734. /*         AAI mode.                                                                                                                        */
    0 D4 G# s4 i+ F3 n, ^5 f. C: ]
  735. /*                                                                                                                                                */
    7 [1 m# _( C1 [( g7 |0 k9 L
  736. /* Input:                                                                                                                                */; Q5 E0 n( b# i
  737. /*                                                                                                                                                */
    3 t: Z2 j; S8 Z6 J3 L1 v- A  u( t! }
  738. /*                byte1:                1st byte to be programmed                                                        */
    & l; Q* Y3 h4 G% C0 t! E, v
  739. /*                byte2:                2nd byte to be programmed                                                        */
    & P! @0 a7 M9 ^0 k: f0 l5 @
  740. /*                                                                                                                                      */
    ' @, K7 a' ]+ C; Q" w" I: G! k: c
  741. /*                                                                                                                                                */
    % d% V& n% p7 D) N
  742. /* Returns:                                                                                                                                */' U" G3 v$ i: @1 P; z% _
  743. /*                Nothing                                                                                                                        */
    : L% Z$ _" a# F
  744. /*                                                                                                                                                */
    8 O+ R, E/ ?3 x9 R6 T4 e: [; |5 @
  745. /************************************************************************/- c5 A9 Q: M4 m) I: h9 s
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    7 q1 z! j( v7 U  I  E
  747. {
    7 Y! K7 b* s& h- C) _
  748.         CE_Low();                                        /* enable device */
    * R% L+ q+ g; i5 T+ h/ o
  749.         Send_Byte(0xAD);                        /* send AAI command */1 h4 R" n& i7 n) x+ r
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    0 Q9 ]+ L, X4 L3 B/ d
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */3 N! A9 b& D$ H2 a7 G
  752.         CE_High();                                        /* disable device */
    ) d& i' P' e1 t+ ^& J9 W
  753. }
    % ?5 z/ D- @3 C9 f; k1 q
  754. + \+ |; m: O) z$ l8 H1 y5 ]
  755. /************************************************************************/9 P) o+ I- W2 L4 n8 [5 y3 z
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    1 A! @, e# l& q! h" x; D& X. X
  757. /*                                                                                                                                                */
    / O2 o! ~8 |# a, d
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    ! O; k6 n3 Q8 E' E1 u6 z
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */0 H. ?6 \6 `, W3 |  ?
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */7 |% h9 ?8 }- R! u
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    ' X) @$ Y+ ]" V/ l3 F* |- J
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */0 n; R: z1 d: Q4 m' B
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    3 I# p6 x& z+ H/ Z. {2 t6 ?
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */; ^- e7 I2 l" G+ E7 {
  765. /* Assumption:  Address being programmed is already erased and is NOT        */! ^4 W; p2 e: t' G. D2 i" i/ I2 |
  766. /*                                block protected.                                                                                */1 a& q; u& q4 k* f# t
  767. /*                                                                                                                                                */
    1 H' x6 \, l/ `+ R$ @
  768. /*                                                                                                                                                */9 v9 S9 N; p8 C) u  }5 x; C
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ' R2 O1 _. `2 M
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */) W* ~# N, k4 l7 |7 Q- U2 d
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */$ O2 G* U1 H6 k# V: O9 }
  772. /*          to exit AAI mode unless AAI is programming the last address or                */1 k3 o8 Z# q& J' m
  773. /*         last address of unprotected block, which automatically exits                 */
    ) v3 P: F- l' }6 o7 m2 b" L
  774. /*         AAI mode.                                                                                                                        */" d! {6 C2 m, W0 m2 \* y' v3 L, u
  775. /*                                                                                                                                                */7 W; e. Q& U1 ]/ ?# J6 d/ N2 {" I1 H" ^3 G
  776. /* Input:                                                                                                                                */
    ; h' }* t$ ]8 ]8 _- `! b+ C( H0 s/ e
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */5 b: H, U9 a- }" P/ W7 \0 i5 G
  778. /*                byte1:                1st byte to be programmed                                                        */" F! \& k) K. G- G8 g+ @0 l) V. B
  779. /*      byte1:                2nd byte to be programmed                                                        */* p6 d- k- B5 p) {6 z
  780. /*                                                                                                                                                */
    . }* \( _1 q  \2 D
  781. /* Returns:                                                                                                                                */
    + W& G7 w! M' Q( u: A
  782. /*                Nothing                                                                                                                        */
    , U! z! @  E6 R, G4 ]
  783. /*                                                                                                                                                */
      ~: {  ~% N! x9 ^. R
  784. /************************************************************************/# I+ z8 @: i$ C2 E; c2 f! C1 q
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)/ P' Z, @& m) z" B" W, H0 b
  786. {, ~' ^6 n# e; G  `' \
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    7 F1 O( x; e' l1 R

  788. $ i; O, N* W  q* o7 F
  789.         CE_Low();                                        /* enable device */8 J" E* v# ^& F- n$ f3 s6 [: F
  790.         Send_Byte(0xAD);                        /* send AAI command */
    / i6 K- E6 C  L( D0 A0 I
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    $ t% _! i8 W% H, a. x. _
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - m0 m' v% h4 d
  793.         Send_Byte(Dst & 0xFF);  Y5 j/ i! q' ^0 A' H3 i! }3 c
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        ' e2 }/ `3 Q7 k
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ) Z1 m+ h% C& c- m; g) P
  796.         CE_High();                                        /* disable device */
    9 T5 ~3 Y. _0 j* _7 v
  797.         / @7 Y: y5 E1 |9 ^# ^0 @" o5 W1 U
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    $ `7 u$ X; T; Z8 w; {' K! A
  799. 1 S8 [/ M/ \' t$ S- _
  800. }
    7 J" Y7 x0 i" A( x
  801. : X" n6 Q- w7 j
  802. /************************************************************************/
    . J9 q0 W& t# r. ^
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    5 `" M6 P# r- d% U: l- D
  804. /*                                                                                                                                                */" u# h1 E1 v( I8 D# c! n! [
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */3 ~2 j# b) Z* X: F7 Q% E$ N
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    9 N7 o& U2 y& w' y- H
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    ' a6 n2 v# s8 M- @, f! B
  808. /* the device.  The 1st data byte will be programmed into the initial   */2 x: t- t8 j7 U, O& ?# v% I
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
      H) p" j8 I. [5 a) O
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */: b; L& Z) n/ \8 H  }' `% d
  811. /* used after Auto_Address_IncA.                                                                                */
    9 i6 W0 b. K. X. E8 @
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    # q/ C" w# s$ C7 b# Z5 t
  813. /*                                block protected.                                                                                */
    " `" s3 L/ _) }  `3 ~* H. |
  814. /*                                                                                                                                                */
    : A: K' P& M) p. o7 n5 a, L
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ' S8 ~: T* C$ M' N  ~
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */5 f* ^5 e. y: y5 _& \
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    1 a" ~. X8 Z, ~4 {1 d# O/ Z1 l
  818. /*          to exit AAI mode unless AAI is programming the last address or                */( O' ]! R! R( ~7 F: v5 Q% d! H' V5 T
  819. /*         last address of unprotected block, which automatically exits                 */8 y8 e, d6 u3 _/ z, i
  820. /*         AAI mode.                                                                                                                        */0 n7 j9 L+ f  W9 v$ g
  821. /*                                                                                                                                                */
    6 s' l: y7 p. A  u" [2 B: c
  822. /* Input:                                                                                                                                */& \. d. F( J3 z+ Q! d
  823. /*                                                                                                                                                */+ Q8 d" f; W$ A
  824. /*                byte1:                1st byte to be programmed                                                        */
      K5 U1 I! h1 Z/ E7 f
  825. /*                byte2:                2nd byte to be programmed                                                        */' L8 C" |& |: R$ J2 @4 f7 @0 e7 W
  826. /*                                                                                                                                      */* Y, g8 a. t  R( J$ E+ l) E
  827. /*                                                                                                                                                */
    5 p0 ~; @# {/ R- @' F( f* V
  828. /* Returns:                                                                                                                                */
    2 W* @( r1 ?+ i& ]( x8 C- f# D' \
  829. /*                Nothing                                                                                                                        */
    + V# e6 n' }  a* C
  830. /*                                                                                                                                                */# l% i6 I' C% n0 \! ~& \
  831. /************************************************************************/0 R0 A2 E/ X  m6 ?. V- {
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    ' e) e7 m* d1 J7 h, P0 T
  833. {
    2 S! H0 _4 o0 a+ J1 H" J
  834.         CE_Low();                                /* enable device */
    1 U# I/ \/ W* v+ ~! c
  835.         Send_Byte(0xAD);                /* send AAI command */- F( O4 N) D, S3 D1 z
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    ) A4 `. N4 z- P
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */% C  k2 M8 X' j* t  }# \
  838.         CE_High();                                /* disable device */8 V- e" `$ R) H( y, i
  839. / O( S$ K% g5 E, n" n" B
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
      l% i4 @# T2 k+ i) Y7 x, i) _0 @
  841. 6 ?; Y- T; _! y# }
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    9 _& L! \; B7 t% _' {
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
      V1 l! s* ~6 g) u5 U. g# ]1 f) ]
  844. }$ o1 a3 p  U4 n0 N8 p# a4 l* R

  845. 6 b/ D0 z8 d- \9 |
  846. /************************************************************************/
    " P4 k8 K4 u0 B& _% B3 B
  847. /* PROCEDURE: Chip_Erase                                                                                                */0 E+ d3 O. i3 o& {1 G
  848. /*                                                                                                                                                */
    : }: Y3 k/ c! i) s1 {" N. \
  849. /* This procedure erases the entire Chip.                                                                */
    5 t5 T" R, q% N# u5 y2 n2 v1 o
  850. /*                                                                                                                                                *// H3 G6 x3 m. A& j: s* ~5 T) s
  851. /* Input:                                                                                                                                */
    $ J5 [/ o. T/ n; y+ a% f
  852. /*                None                                                                                                                        */
    # Z) a6 h) I) y: L1 f/ c
  853. /*                                                                                                                                                */
    , Y7 B4 U! j2 O' {* w. j
  854. /* Returns:                                                                                                                                */3 C" d& ~$ z- u: E; W( t, z0 h, u
  855. /*                Nothing                                                                                                                        */' l( _4 B6 `7 t% H( W: c; L. L
  856. /************************************************************************/
    7 w( A3 ?* g: t  G3 P; S
  857. void Chip_Erase()
    3 g% T! o! r3 t- w
  858. {                                                  S- b# Y. e6 `0 P
  859.         CE_Low();                                /* enable device */
    ; O4 r  j9 E/ }0 v
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */+ A# f/ O' x( w3 Y
  861.         CE_High();                                /* disable device */
    8 f* N# D' I6 s( r2 `
  862. }+ t9 ^  ^7 z# x4 R8 S
  863. 4 k+ e, L, v. F# ^4 @4 t& ?* u
  864. /************************************************************************/
    / l3 i+ l( j7 s6 i
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    5 g: W7 B$ `( v2 A, j
  866. /*                                                                                                                                                */
    # s& v- q4 G0 h7 m5 {7 U3 v  ^4 w& H
  867. /* This procedure Sector Erases the Chip.                                                                */
    6 i3 {# c9 f" e1 v/ V, I' W8 C
  868. /*                                                                                                                                                */
    5 A' g2 Y8 v4 W+ K3 B
  869. /* Input:                                                                                                                                */
    * e. S) P& Q" p
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    1 m0 H( U; t" ]6 d8 k% C8 P' b
  871. /*                                                                                                                                                */9 ^/ o2 X# }+ z  ~- K+ Y
  872. /* Returns:                                                                                                                                */
    , n3 W& A; E' x5 J: W1 V3 O& Q  Q
  873. /*                Nothing                                                                                                                        */: Z8 W6 A* F: H/ d
  874. /************************************************************************/2 l  P7 b: `1 ^) L! H) k
  875. void Sector_Erase(unsigned long Dst); x  s7 `# |- ]' p: g
  876. {
    1 f% d& a  }$ V: t

  877. $ Y2 R5 _# x: P$ F
  878. $ c" w* L' E1 G& z: e4 Y
  879.         CE_Low();                                        /* enable device */- ?( ~9 ~5 L) o5 }( G( {
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    ' o9 d- T$ n1 ?
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */" z4 L( L! X9 Y7 ~
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ! z3 n: b5 _0 E9 e
  883.         Send_Byte(Dst & 0xFF);
    5 H/ J) g+ V8 i7 Y* A
  884.         CE_High();                                        /* disable device */; i7 G2 Z% M* q$ D7 K- X4 L  n2 \
  885. }        ( c, a5 n& C& J5 M1 H0 F) ?8 {
  886. % q5 W+ K9 x" I0 D% X0 G; N
  887. /************************************************************************/+ \' w2 j$ P/ X$ V! z
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    8 g" b/ ^# U" v$ G3 ?
  889. /*                                                                                                                                                */
    , B4 U6 V# a# k: u; \; Q
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    - X" K8 f* v: h/ P: O- u% m, A
  891. /*                                                                                                                                                */. n" t4 O# D1 v* y! G' {1 r5 a
  892. /* Input:                                                                                                                                */
    ) E* }" b4 R7 V1 J0 i1 S8 x
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */( z/ ]+ d4 x' W! l& C" V3 p: P- K
  894. /*                                                                                                                                                */
    ) S: }/ R# ~9 F, l' r
  895. /* Returns:                                                                                                                                */
    % C! ?# i# _8 m
  896. /*                Nothing                                                                                                                        */  Y/ g2 F7 t. W' y# }
  897. /************************************************************************/+ o# L7 T9 d3 Z# R$ a# V
  898. void Block_Erase_32K(unsigned long Dst)
    / W3 Y: N/ C$ D
  899. {1 k- Z; _9 ~; {# o/ {" q( |; X# N
  900.         CE_Low();                                        /* enable device */
    : y. i2 f$ I4 l% m# R
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */0 Z) f* E, R# z, E2 n) T
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */, S2 y, y. N6 t" |4 m5 G) _
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));7 \# y+ Y. y+ R* K4 n; p9 h5 Z! l0 w
  904.         Send_Byte(Dst & 0xFF);2 ^7 k" B3 m6 o
  905.         CE_High();                                        /* disable device */
    5 Y3 p. G& \, g3 v8 J; p/ r+ q
  906. }
    " v7 l$ K: b0 Y2 `: S7 R

  907. 6 s5 I1 S/ p" h: t+ p4 G
  908. /************************************************************************/
    & n* d0 B3 K$ b5 _" q  S
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */5 D3 S; R) o& t8 P( V! A# k
  910. /*                                                                                                                                                */) E4 e4 O  M; {% @+ g7 G0 l
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */, X& }) @: o( }$ Y7 g4 X
  912. /*                                                                                                                                                */7 z* s6 ^0 Y1 W/ R) h  j4 f
  913. /* Input:                                                                                                                                */
    ; k4 N3 K, s0 ~  x  M
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */  u6 A7 C0 F: O! [3 X* Y& H" o
  915. /*                                                                                                                                                */$ _' P! |3 F8 l( m6 B* U
  916. /* Returns:                                                                                                                                */9 s: b  f  I$ R% R. ~; o- U
  917. /*                Nothing                                                                                                                        */
    6 W6 e! f  f2 ^8 y
  918. /************************************************************************/
    ( W3 H+ ^! ~4 |
  919. void Block_Erase_64K(unsigned long Dst)+ i/ K& E* P" B, ?* S' [
  920. {
    3 H% i. l8 N6 u. x. o2 h
  921.         CE_Low();                                        /* enable device */# D* [& `2 h/ j; i4 g/ ?
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    : [- X; c% j8 [/ Z% Z( }
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    " F( t4 r, K8 i8 f. l
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    . |" a) A( Q/ ^
  925.         Send_Byte(Dst & 0xFF);  x) V+ V, U$ H
  926.         CE_High();                                        /* disable device */, Q7 z% v9 ]: o- [9 x' W1 i
  927. }
    + C$ o" K6 d9 O
  928. & c* t3 I$ w* `+ w9 i. x3 M7 S
  929. /************************************************************************/9 q. E9 t' b: H, y. O
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    ( [% [6 X1 J5 P/ T0 I1 Q/ B& u5 G
  931. /*                                                                                                                                                */
    ( s, f% q) t7 J2 z
  932. /* This procedure waits until device is no longer busy (can be used by        */: D  g' c$ }& v- q/ z- U# k
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */, k( P) x; ]  b; z/ C! Z# c
  934. /*                                                                                                                                                */3 T( U; o- r9 r! X6 K: @0 m
  935. /* Input:                                                                                                                                */
    # z) B0 g! i" f
  936. /*                None                                                                                                                        */+ c: ]! ~) D' K3 x& u5 V
  937. /*                                                                                                                                                */8 s6 Q: U- Z. m( {' T/ r
  938. /* Returns:                                                                                                                                */
    & ?+ D* @; c3 C9 v" {, H5 u* x" M8 o
  939. /*                Nothing                                                                                                                        */
    / s  i9 S6 B8 v+ j
  940. /************************************************************************/# f; C5 Y* U% \+ N
  941. void Wait_Busy()7 [6 s% p2 v4 h  O6 N
  942. {- R$ ?; Y# s/ [+ j, _8 \( _
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    & m6 y8 ]' Z* v8 M7 D1 ~
  944.                 Read_Status_Register();4 G; I4 v+ A, }$ U& I; g
  945. }
    : x8 a& u  c* \% t" L3 w/ e  Y

  946. - s% I/ S% X& [& U: l* I
  947. /************************************************************************/. w( @' A" T/ p4 m1 {4 Q) x) c
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    ( S& X$ z5 ~- m0 z2 z! ^% r; o$ _, c
  949. /*                                                                                                                                                */, O' |5 [: v" ?4 V
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    8 Y( S3 B, l% u* `& K
  951. /*                                                                                                                                                */
    5 C" y( H5 T1 F* Q1 M( O
  952. /* Input:                                                                                                                                */
    6 r& C/ t$ M" }5 B
  953. /*                None                                                                                                                        */( I: j0 y! c# C# \* j+ e, l
  954. /*                                                                                                                                                */
    - s% F0 T% e* s% W
  955. /* Returns:                                                                                                                                */& Y, i) Z8 Y: x; U1 x8 x
  956. /*                Nothing                                                                                                                        */
    * P& N4 ?" k  @/ s
  957. /************************************************************************/% I4 z; T$ v0 w5 T2 m
  958. void Wait_Busy_AAI()
    3 l6 s! t  |2 e( O; c
  959. {8 T4 _2 c' ]' T: K, i$ [( L& M
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */3 v# D, G. ~  ~2 B
  961.                 Read_Status_Register();. F4 ^0 |! f7 W4 W) z: l
  962. }
    2 |$ s$ b- |1 |; ~; i/ n
  963. # ~3 Q5 `9 ^9 s  j- ]0 K1 G
  964. /************************************************************************/
    # N0 q; P3 [! x; c
  965. /* PROCEDURE: WREN_Check                                                                                                */; ^0 B( ]7 r% z# x2 x
  966. /*                                                                                                                                                */7 x: K; s9 p& Q/ h# `" C
  967. /* This procedure checks to see if WEL bit set before program/erase.        */- X. t5 B" `. p7 G2 N( q* K
  968. /*                                                                                                                                                */
    4 s1 |1 b2 U1 S1 V
  969. /* Input:                                                                                                                                */
    - c3 e* P3 G. r( _5 O7 n, `
  970. /*                None                                                                                                                        */
    - C1 C# a; \/ Y) u8 `, Q. X5 h
  971. /*                                                                                                                                                */
    ( o3 A; K2 ~9 _' |& p' v" e5 a9 g- \
  972. /* Returns:                                                                                                                                */& R, E; K3 ]+ q( i; v
  973. /*                Nothing                                                                                                                        */
    ) l7 O4 {8 d* d1 p
  974. /************************************************************************/
    2 n2 H0 k) O; Q' W8 b2 N
  975. void WREN_Check()' M5 l8 C" X" b
  976. {
    7 w1 |/ d, \  k" S/ l8 r
  977.         unsigned char byte;
    ' I0 J$ t5 w/ @+ x2 c6 c# L
  978.         byte = Read_Status_Register();        /* read the status register */# Q0 V( D; T" W
  979.         if (byte != 0x02)                /* verify that WEL bit is set */; ?2 x) W! T" `) m+ U/ J8 G- ~+ E
  980.         {
    : @/ A7 \) X1 \8 X6 K$ M
  981.                 while(1)
    ; f9 y- o; Z: t  a% J9 O" i- T
  982.                         /* add source code or statements for this file */
    7 i& B( \/ ]& b. _
  983.                         /* to compile                                  */9 J0 U2 L/ O1 `* J* G$ y
  984.                         /* i.e. option: insert a display to view error on LED? */2 u9 }  A+ Z% R3 z! Q$ e( \4 u
  985.                  5 j9 y& t9 m! f, X
  986.         }
    & j# d- M) S6 b
  987. }
    6 w# `/ ^6 F; p, v
  988. * C* B- G8 ~2 y$ a9 G
  989. /************************************************************************/' W9 }4 N8 o( d0 J4 @
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    % Z# j* I+ B" }3 U3 W& R5 p$ j
  991. /*                                                                                                                                                */
    + g1 O: a7 u& f* T
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    1 O- R3 U2 {1 n  r3 [
  993. /*                                                                                                                                                */
    ; T. v* l, Y! L2 R9 u9 y' W
  994. /* Input:                                                                                                                                */
    7 ~$ n9 u: h1 B
  995. /*                None                                                                                                                        */% E. [6 J1 d. d  d  ^
  996. /*                                                                                                                                                */! c1 ^! ]3 s2 J! k
  997. /* Returns:                                                                                                                                */
    . I" r  G8 G" c7 P' o
  998. /*                Nothing                                                                                                                        */! ]6 y8 l2 r0 k; {* N0 t. }
  999. /************************************************************************/
    5 a/ |; Y- g0 p( N
  1000. void WREN_AAI_Check()1 g1 [; D2 v0 @1 H- u% I  y' z
  1001. {
    , P* I+ ?# Z$ k: c" n* r  V9 g; H, @
  1002.         unsigned char byte;
    & W/ ~" g- z# X+ I% t
  1003.         byte = Read_Status_Register();        /* read the status register */
    0 k" v- b+ `! w3 I- P2 ^* {& O5 @
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    , _& p6 p* t1 X- B$ ]7 u
  1005.         {5 C3 P6 b& m+ P4 s) Q8 _
  1006.                 while(1)               
    " ]6 C+ h7 H& j. w
  1007.                         /* add source code or statements for this file */6 \, g' M& T1 B7 S
  1008.                         /* to compile                                  */
    4 Z: F, Z) j' a
  1009.                         /* i.e. option: insert a display to view error on LED? */" J5 ^: S! ~& W: S' T; p
  1010. ) A) a7 r5 c( O% I0 p
  1011.         }
    6 r6 o0 R  O4 Y
  1012. }' |2 J. E0 a$ b; z% r5 f
  1013. + n: ?  ]2 Q$ r) G+ f
  1014. /************************************************************************/
    ) J8 j' u9 Y, A, p* J0 D, }% d
  1015. /* PROCEDURE: Verify                                                                                                        */' X% J; {% x% z( S. o
  1016. /*                                                                                                                                                */
    7 d+ q6 [1 K0 |9 y+ [. O# a8 f
  1017. /* This procedure checks to see if the correct byte has be read.                */$ p1 \* M+ I/ n! u5 t2 `
  1018. /*                                                                                                                                                */
    # G) a) c0 g! h. L& U9 c8 f
  1019. /* Input:                                                                                                                                */
    & h+ z$ p+ q& d: a& X% }% r
  1020. /*                byte:                byte read                                                                                        */& A# I* F( l7 X, Q
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    5 h6 Q& D+ G0 \, x" _' E
  1022. /*                                                                                                                                                */
    / t" R- S( `$ X3 b* I' q
  1023. /* Returns:                                                                                                                                */' ~4 @! J4 Z/ _
  1024. /*                Nothing                                                                                                                        */
    . x: \) I# O$ T, W9 l1 A0 T( v
  1025. /************************************************************************/
    8 A8 {/ ]/ D. ^1 [4 _7 z' ?4 n
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    1 `7 P& N' L# Z0 g
  1027. {6 f6 ~+ F' D4 L  U% ~/ I2 M  j2 @
  1028.         if (byte != cor_byte)8 {5 d) t# I& k) Q6 Q
  1029.         {! ]7 S, i* k/ z' [* L$ u
  1030.                 while(1)
    9 M  e: f4 u$ o6 B7 S  i! z* V
  1031.                         /* add source code or statement for this file */
    ) j) {* K% s% J! [5 j+ J0 p$ Y4 U4 w& C
  1032.                         /* to compile                                  */1 F& Y- W* F1 a/ D
  1033.                         /* i.e. option: insert a display to view error on LED? */( Q" ~/ Q$ `' Q9 a! }: `' G
  1034.                
    - I8 y$ j( L. {3 U& I9 a9 e3 s
  1035.         }
    ( L3 y, {  K( C2 D
  1036. }
    . F) E( R" _- I5 d( C7 ?
  1037. 2 J. v/ |/ c- d6 s" m4 H+ W7 l/ T

  1038.   V6 t4 w, H9 b4 K2 D4 F! |8 B
  1039. int main()
    # e/ ?* g! x+ j% }' k8 e
  1040. {
    ( b4 j, ?- n- F  }, b
  1041.   T) w7 t% h5 b+ Z1 ~
  1042. return 0;
    5 X0 d; D1 u8 ^: r6 T1 v
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
+ p1 V6 [% x% `/ M8 ?# {   main()
  f% l. G# e- u8 v  n% _   里面怎么是空的呢?
/ p% i7 g- U' ]/ v& Q0 h5 P1 C   发一份给我吧" ^$ ?$ |9 Y: @
mail:luyijun2005@hotmail.com; i. G8 W' h. f9 z" N
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
: U  P" e" k" s* p! i' {+ z$ z. V( ^5 l- ?% p
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。! D' x7 L7 K  g3 n) `, I
EC的代码在哪跑,你看DS的说明,每个EC都不同的。/ X+ O2 l% t5 a' e( ]
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
% Z# J5 M, o% w# n/ C' J上面几个问题是你没看任何东西而白问。
/ t) n9 L9 z6 N  [' \4 I" T
% Q. c! Z, \6 Z+ p至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

# K1 C. L4 g& _/ ^# s- R关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”' i0 T1 B$ I- V: o
1 R8 `/ c8 Z& T3 z$ V4 z0 ]
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
% P& N9 l3 @2 h& D6 n" K( v
. F" }- ]4 ?: q- w4 I! k不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
6 z: ~4 L/ ~8 p# [. S+ e& p+ {似乎要把SPI能support 到最大,这EC chip应该有好卖点
$ e8 R  P) H1 E7 D0 |- hBIOS功能要不要强大,也就决定了SPI Flach的大小
) O/ |+ x7 B1 H3 m我是这么想的~让OEM去决定要挂多大!* p" s) K' j+ t- j  A" w
如果我司有BIOS工程师就好了~哈
0 |& o9 K  L/ O, T! @WPCE775应该算很新的东西,来看它支持到多大?
4 {$ p3 T( P9 G! y. x1 Y' D+ V3 K  x* Y5 o9 b+ @: t: m
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
' q. D4 R$ `% Y1 w. {: O8 [" m" E其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.7 F1 n) U" L, C9 n7 j2 \
* Q0 G8 Y% D# s& a6 s
这份driver收下~希望以后有用到' l7 V/ M8 ~4 R2 O, t6 C3 v2 e
谢谢bini大大
) h  z; F- C0 b0 a% {: s# j
  R8 n) i, I' p( a, R0 E$ M很新很新的新手,如有错误请指正 (准备看第二家的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()" T$ h# c2 S4 e* U* `# G, W9 _
{
0 S  q. Z7 A* G+ a4 a# A/ I        unsigned char temp = 0;. v) _4 E0 h, x
        CE_Low();
, Y3 ]2 s: j6 K. q5 L. g$ l    while (temp == 0x00)        /* waste time until not busy */! K$ M3 @. D2 f- V3 B  h' |9 z
                temp = SO;6 ?% ?3 E3 [" I& J- R
        CE_High();) w& l, L1 x9 }! U
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)5 \0 `% G+ B2 Q
{- R  M0 ?* L) z/ Z# w' V/ L' W
        7 e4 R) `2 |" Z) a
        unsigned char i = 0;
# g$ b' Q% N$ @5 C) \9 v* I8 m: r        for (i = 0; i < 8; i++)
* Z0 z. Y% L. O% \7 }        {" {# U! f6 r/ C, p
                ! `7 \! @+ i7 K. |; R! y
                if ((out & 0x80) == 0x80)        /* check if MSB is high */# u! [1 N7 R' l7 @( j& y
                        SI = 1;
" P9 U. S' |7 s, m                else
7 J8 Y% D0 M, p! k3 @' K8 O8 U                        SI = 0;                                /* if not, set to low */. R' N  p" I3 g
问              SCK = 1;                                /* toggle clock high */
& C' F) u6 ^0 \   题            out = (out << 1);                /* shift 1 place for next bit */8 O% g% X4 y: c6 b: ~: N
                SCK = 0;                                /* toggle clock low */
! p* [" ^. \  Q9 N        }
9 B0 H6 M3 F% N5 {}/ P8 x! ?. W  v* M8 t6 L
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-3-15 05:37 , Processed in 0.450885 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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