找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55443|回复: 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* V" f# B8 h/ m  a
  2. 6 J; ?7 z) v- `
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory5 n3 G" ?2 s0 S  _. y8 E% x8 I

  4. 4 c2 X* I" m4 h' L+ S: m3 O
  5. November 4th, 2005, Rev. 1.0% Z- W: F" p4 b
  6. 1 l. N% ?8 c8 q. t1 w) x. x
  7. ABOUT THE SOFTWARE
    6 B' S3 C6 e+ @# d
  8. This application note provides software driver examples for SST25VF080B,
    " w& q5 [- i! X: K
  9. Serial Flash. Extensive comments are included in each routine to describe   f5 e$ o" A* a, K
  10. the function of each routine.  The interface coding uses polling method
    $ A' w! N- r2 l- S; q
  11. rather than the SPI protocol to interface with these serial devices.  The
    4 w$ m2 q  G5 e; r+ K! B+ Q
  12. functions are differentiated below in terms of the communication protocols7 e/ [% Z$ O3 O8 q, g
  13. (uses Mode 0) and specific device operation instructions. This code has been
    0 m- z! Y$ I  G! x4 ^& {
  14. designed to compile using the Keil compiler.
    7 y% i6 A& p" E; M. K
  15. ! _- J; {- j8 N
  16. . q1 W2 k# w7 j+ X# Y! ]
  17. ABOUT THE SST25VF080B
    0 |- S' j& `) U5 p
  18. ) j$ V4 e  C2 @; _
  19. Companion product datasheets for the SST25VF080B should be reviewed in 0 C* A/ p, }# u& }. ]5 p' |
  20. conjunction with this application note for a complete understanding
    + Q8 k" R& T: _' a, W' d) r
  21. of the device.% S5 ~: n! ?) u8 e1 q3 t' K
  22. , W- I, z2 d- U

  23. , X3 r' ~. T/ {6 c
  24. Device Communication Protocol(pinout related) functions:
    1 Q% i, h8 R% `) Z2 W$ i3 q: Z
  25. ( ?' t3 p6 U& p2 l
  26. Functions                                    Function
    & K7 I! W* i) p+ z# P
  27. ------------------------------------------------------------------
    3 }( Z( B: K6 ^& p% z$ z
  28. init                                        Initializes clock to set up mode 0.; G6 H3 j. I& C# p" [, q! k
  29. Send_Byte                                Sends one byte using SI pin to send and ' J# P7 E0 o, |. s- m
  30.                                                 shift out 1-bit per clock rising edge
    ' Q5 Y5 I- }' ^1 e  h& Y% l5 x
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    $ y8 a8 I8 X2 O$ J7 l
  32.                                                 in 1-bit per clock falling edge
    8 f4 k# o3 w0 w2 e
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming4 g9 V+ N  k, c) f  G3 D' O
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high8 l; G7 A; z- f2 B# P" [
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    0 P% V& ~0 `! m1 U
  36. Hold_Low                                Clears Hold pin to make serial flash hold
      U( l6 w  ^$ M- E% O0 \% `
  37. Unhold                                        Unholds the serial flash1 o8 a$ e2 M+ i# l
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    / `: D0 \3 _! W& T9 g
  39. UnWP                                        Disables write protection pin
    ( h' I- j* f+ r

  40. 3 X# a1 M/ w% w) m9 V
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code0 A) a. R7 U% p/ o
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your8 S! P' u5 i& t
  43. software which should reflect your hardware interfaced.          
    / W! ]- V) x, [; F
  44. 8 W6 A/ j( B% C' ]' @' B( g2 w

  45. 8 {+ ^, E; D( x# \. G3 v8 J* J
  46. Device Operation Instruction functions:
    9 o! K% Z. j2 d$ Y% T- K

  47. % ~  I# W: I& b  h. v! q0 f, U3 J
  48. Functions                                    Function
    0 _9 N; N. H$ o/ M2 n- i) `) s
  49. ------------------------------------------------------------------- `' }5 \6 ?  g* s/ O! `
  50. Read_Status_Register        Reads the status register of the serial flash; c' M9 ~9 {9 h9 [1 O% v
  51. EWSR                                        Enables the Write Status Register
    * F9 `/ Y0 q! _4 g. d5 d4 `* I" K8 x
  52. WRSR                                        Performs a write to the status register6 O0 |9 J% Z1 A: D6 x
  53. WREN                                        Write enables the serial flash* E: O! m/ ]2 J3 T
  54. WRDI                                        Write disables the serial flash7 B9 h& T$ f6 ^" o( L$ }, S0 J9 E
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming5 V7 t  m# W5 F; @
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming9 f! A7 E9 M9 d
  57. Read_ID                                        Reads the manufacturer ID and device ID9 b* j: e( _9 _/ X" i9 o/ E+ q
  58. Jedec_ID_Read                        Reads the Jedec ID
    / V/ {( N, i! ]. h7 |  Q7 r
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)1 z7 r' l3 G# B  Y5 R& ~; V0 i
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    0 A; [* Q# S  t5 W4 U
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    ( d# X* {( P! F& l: g! X
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    , z  \6 ^( w* J5 @
  63. Byte_Program                        Program one byte to the serial flash$ w$ r/ A. W2 U3 d3 S8 b
  64. Auto_Add_IncA                        Initial Auto Address Increment process; O' B7 v3 B2 ?; f3 h
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    $ t  r2 }9 K0 {& N/ g3 q7 j: p! D
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    4 S0 t" Q, a; ?& N. ?) \
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    ; r5 L& h" {& a0 W% d  O& C# a
  68. Chip_Erase                                Erases entire serial flash7 i9 {+ ]& N- E: N2 M
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    ' B1 W8 Y8 U9 k1 c- l7 n
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    ; t0 \9 a# K- {  X
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    ! L  w- s6 N1 X* y
  72. Wait_Busy                                Polls status register until busy bit is low
    ; Q* A, l' l/ ]: b
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
      u- m3 S3 d' i5 M9 [0 B
  74. WREN_Check                                Checks to see if WEL is set3 c/ }% t8 z  z7 d3 J3 H6 x  r: D
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    6 v5 M# \2 N, ~+ z
  76. ! c3 O; [3 F- D! i: s' M# s& L
  77. ; ?7 n1 O$ a# R" O
  78. % n. v! C6 }8 `4 R2 y
  79.                                                                      & l# B" U/ Q4 M4 o& o: q
  80. "C" LANGUAGE DRIVERS
    6 U. Q' P8 T5 k( K7 Q6 H4 g2 @
  81. & G5 ]& s; l8 g
  82. /********************************************************************/# D/ i) A3 v4 ]( t
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */7 B; ~  T4 v8 m
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    ; B' I6 t3 W8 {4 q
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    . U# @8 W: v7 y! v4 N( e0 @
  86. /*                                                                  */
    ! k. ]/ f) I( |; ]+ Q
  87. /* Revision 1.0, November 4th, 2005                                                                          */   ! u( h5 l" h3 x4 N
  88. /*                                                                  */! P8 n! ?  n! M8 B7 m; C+ t2 G6 }7 [: j
  89. /*                                                                                                                                        */+ o, ?3 X# \2 e& n% l$ U% W
  90. /********************************************************************/- S: o7 F9 `7 u1 A
  91. & c; g9 b9 m2 v9 _5 F; [+ d
  92. #include <stdio.h>
    ; n: P) h* V, `0 b3 L1 m: j0 L* W
  93. #include <stdlib.h>" O% T( h& e+ T" t1 _

  94.   g0 K/ v# d. u3 Y( K
  95. /* Function Prototypes */) x9 V. _8 J# l% p/ `4 Y$ Y. m

  96. 4 l! ?$ b. _' F" V1 r5 v
  97. void init();
    * \2 i1 n  L( T5 I/ P% K
  98. void Send_Byte(unsigned char out);
    5 T  p0 ^/ U1 F% i
  99. unsigned char Get_Byte();( K- N$ ~7 ~1 w' X* {* G, A! Y* ]
  100. void Poll_SO();
    + E7 B8 W5 j9 {6 r7 q, N+ O/ O2 a
  101. void CE_High();4 D# I2 P% |% k4 i, t2 p( }, s
  102. void CE_Low();  q0 I( X. }% p4 _0 N4 V0 T
  103. void Hold_Low();
    8 U% M+ q" `' N2 y
  104. void Unhold();( k- j2 ^: ^  L2 P2 W0 {9 Y& y! S
  105. void WP_Low();
    & i. |3 \/ T, E! ^7 r5 a
  106. void UnWP();! C/ S! P& j' c6 ^% X0 ]1 ^& ~
  107. unsigned char Read_Status_Register();
    1 Y' b7 S4 k8 N% U
  108. void EWSR();$ S  H6 h( p- H  H% d
  109. void WRSR(byte);2 U" b3 I1 W$ y3 U, r% N9 [
  110. void WREN();
    1 T6 @8 v# e' y6 m# {
  111. void WRDI();7 h2 V# l+ Q; t) y- S9 b" C9 w- D
  112. void EBSY();
    ' m( \  T) A2 }1 e* C: Y3 N( _
  113. void DBSY();
    % h; ~# H0 I: ]) d1 n
  114. unsigned char Read_ID(ID_addr);+ a+ T, S3 W8 @. g5 ^
  115. unsigned long Jedec_ID_Read();
    2 ^; @; K3 s+ s; i
  116. unsigned char Read(unsigned long Dst);: K6 A. U0 R; l  K3 N$ |
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    * O! A9 _8 Q( w! l* U, |0 k
  118. unsigned char HighSpeed_Read(unsigned long Dst); 3 c5 b3 L* I# m$ Q( t7 \2 F
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    6 V6 }' b' h9 C1 @* [3 f
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    - l$ b# n; K( a) P1 k( |
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);4 }2 g4 G# W5 u! q
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);+ \; F/ ^% i3 n3 ^: U! G
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    + G2 Y9 F) y, ]2 \8 i- q1 ]
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);% U% L  o8 `7 E) m
  125. void Chip_Erase();' h$ H& B9 p% p1 `
  126. void Sector_Erase(unsigned long Dst);
    7 k6 ~9 {# }! r. K* `( l. J9 ^  W
  127. void Block_Erase_32K(unsigned long Dst);6 N7 C: Q/ C* g
  128. void Block_Erase_64K(unsigned long Dst);
    . v' i) E* u% B$ b
  129. void Wait_Busy();
    2 a8 G5 I: D2 b3 N: R
  130. void Wait_Busy_AAI();- y1 X0 H; R: s% _( X5 M, k( q' x$ O
  131. void WREN_Check();* D. J. M0 z! j" `8 F6 g5 l( d" q
  132. void WREN_AAI_Check();
    5 r% X. P7 F, h) ~7 |# Q( y2 S
  133. ) T  v" U8 q1 C. A4 _3 K' W2 m
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    & P+ a& Y% e  Q' G* }; p. r

  135. ( U7 G" _4 b$ o7 E( f
  136. unsigned char idata upper_128[128];                /* global array to store read data */+ p3 `1 q% ~0 h/ Z9 N3 T1 |
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    - s0 \! t4 R5 s; p! U2 ?* g) y
  138. 6 q8 N) L( R* e! N8 D
  139. /************************************************************************/
      F0 q- H- B2 U2 a' B  O* [
  140. /* PROCEDURE: init                                                                                                                */
    - `$ c2 E2 b8 p
  141. /*                                                                                                                                                */
    + l0 Y, C0 ^+ J1 K
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    5 {/ D( ~# P% F+ X9 {; t" C6 j" D0 i
  143. /* setting up mode 0.                                                                                                        */
    + K+ `4 j$ A4 O7 n2 |' b) @8 i. L
  144. /*                                                                                                                                                */' S7 r/ q% v) ~3 x, L& r9 h6 g; M
  145. /* Input:                                                                                                                                */
    - {. a. L# B/ W7 [8 u% v
  146. /*                None                                                                                                                        */
    $ B, R" I8 r2 J# \1 j' d7 A
  147. /*                                                                                                                                                */
    1 u, M' [& E( X/ q7 v
  148. /* Output:                                                                                                                                */
    ) l2 |8 a3 ]- y/ }+ n; J; V# Y4 o# h
  149. /*                SCK                                                                                                                                */
    & y1 K4 F; j" U) _8 q* _4 z
  150. /************************************************************************// r$ k" d+ A* c. H* `( p: _- R! Z
  151. void init()+ ?# u) f# f( w7 v
  152. {5 L% k6 ~  U: Y( ^
  153.         SCK = 0;        /* set clock to low initial state */
    9 x% {( L& r. L  w
  154. }+ V9 A- {; y" f" R$ T8 k

  155. 6 j" A0 y8 ^! y9 C! \
  156. /************************************************************************/
    ) ~0 D* M. A, l+ ~/ w  f  W
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    + R9 U, m0 I7 H& |/ R
  158. /*                                                                                                                                                */+ X$ w% w; o. _: W
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    3 V0 H4 L% Y) {8 c  i
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    / d/ {1 F) X  {/ [* b
  161. /*                                                                                                                                                */
    9 d9 u' N0 O, T* {; I' P
  162. /* Input:                                                                                                                                */
    * D' P+ f* {, [6 D6 u4 ^, A
  163. /*                out                                                                                                                                */' v! Z- `. Z1 F* ^7 p0 c5 f
  164. /*                                                                                                                                                */
    - ~& r* \! u+ F2 q: ~' q$ }
  165. /* Output:                                                                                                                                */
    8 p+ A5 ~% s4 O
  166. /*                SI                                                                                                                                */
    " `, z+ ?/ Q! F  ?* }9 P- {7 t' u( q
  167. /************************************************************************/
    & C: X/ B7 R- u/ M8 @: J0 ^
  168. void Send_Byte(unsigned char out)
    " \0 D* d; b3 Y( r' T
  169. {( x! g$ i7 E. O: _( F/ w# x
  170.         ' q* X+ g# m& l2 V/ V  R
  171.         unsigned char i = 0;7 a1 t5 ]* D4 d) X0 ^" Y4 w
  172.         for (i = 0; i < 8; i++)) @3 a/ k& t0 D
  173.         {
    & a# w) h2 G2 x4 ]  N: S$ k7 t! r2 Y0 e
  174.                 2 ?4 _+ n- {* z4 B& W2 W+ d* S* U2 ~
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */% v4 A+ ^6 ?3 b& l6 U( G: @: ?
  176.                         SI = 1;" y7 n/ F! F& o& l& L
  177.                 else3 p# S: b' z( l: Y. ^1 W
  178.                         SI = 0;                                /* if not, set to low */; b7 I* X2 J' _9 C6 ]( u- P' x
  179.                 SCK = 1;                                /* toggle clock high */
    ; C2 a% i" X' I* I- r
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    / i2 \  }: @; g- ^
  181.                 SCK = 0;                                /* toggle clock low */
    7 g7 ~' O/ W  z  d+ Q
  182.         }
    / m3 L) U6 R" @! E
  183. }* @% ]1 [' Q: f
  184. ! U* m0 @4 e9 q8 `
  185. /************************************************************************/
    ) s3 U( w- K# U0 L. A$ Z
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    4 E2 b, ]. r/ `" \
  187. /*                                                                                                                                                */
    # |# X- `( _$ y# e
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */3 T( C9 j- Y5 \- Y. ~& v7 R
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    ! M* |- _1 R  O, k) A
  190. /*                                                                                                                                                */) Q5 Y# J! ?- L
  191. /* Input:                                                                                                                                */* F7 }: U3 N  O) z6 n, ]
  192. /*                SO                                                                                                                                */
    + M/ x" o- ?1 ~- T2 F
  193. /*                                                                                                                                                */
    & R# @( P' g) x8 |5 E
  194. /* Output:                                                                                                                                */0 s/ ^! P, h7 e& `# }# {
  195. /*                None                                                                                                                        */
    # o! C6 C4 \, }4 a+ ~2 J2 D
  196. /************************************************************************/% H" X% C! ?6 y; F' @0 i( Q
  197. unsigned char Get_Byte()
      I" ^6 _- u) w
  198. {
    5 L; M6 Y- O( ^) A9 k! a
  199.         unsigned char i = 0, in = 0, temp = 0;
    " W) `1 x$ n  l- P0 R% w9 c
  200.         for (i = 0; i < 8; i++)/ {' Z  K6 ]; v( @
  201.         {
    - K/ H( @4 j' {1 |; g  U9 _# Q
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    # F6 \4 w- Y" e; m  ?+ C! H. O% i! I
  203.                 temp = SO;                        /* save input */
    ! O7 M# Z; X/ |- ~' M6 A; m- X' U# T
  204.                 SCK = 1;                        /* toggle clock high */8 c/ o1 M. z! F! F
  205.                 if (temp == 1)                        /* check to see if bit is high */
    5 [: c3 p* @4 m2 K
  206.                         in = in | 0x01;                /* if high, make bit high */
    ' W) {8 t! ^+ v2 V
  207.   N4 b' o0 J  r' J$ m7 W
  208.                 SCK = 0;                        /* toggle clock low */; z! x4 L; q' G0 a3 j$ `, r

  209. : U' N, x7 n3 M8 a. l
  210.         }, |: x9 o  `9 J* \0 ^
  211.         return in;
    ' |! A6 s& O# Y4 U# ^3 [: m' @
  212. }: N- N$ C0 @/ c: V4 \9 \
  213. & h+ L' O. L: F% M: O3 _
  214. /************************************************************************/, S- X3 ]5 R- k8 W6 P
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    " c+ [" b$ j' c6 G
  216. /*                                                                                                                                                */2 U, t- ^5 e& S4 R- l# [* h
  217. /* This procedure polls for the SO line during AAI programming                  */# j# f4 |/ l& a2 r. r4 S
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/, L) }4 U# l0 u
  219. /* is completed                                                                                                                        */
      T( i) T6 ~' ]/ K4 j
  220. /*                                                                                                                                                */+ {$ }; R, A+ }% E) `/ o  u
  221. /* Input:                                                                                                                                */
    + T0 X8 j8 ~9 ?+ Y( G! H
  222. /*                SO                                                                                                                                */5 r) k5 l8 Q* D2 @2 d
  223. /*                                                                                                                                                */
    ! I5 D8 _/ I* X0 Z
  224. /* Output:                                                                                                                                */
    * s* X; c& I# B2 F
  225. /*                None                                                                                                                        */3 j. A) V( k. V- l
  226. /************************************************************************/
    $ y& Z0 w+ N; ^3 }" o- U8 c' o9 B" d
  227. void Poll_SO()
    ) N: z& [' W) H
  228. {% k. F0 s0 k- b2 }7 [, x
  229.         unsigned char temp = 0;: h# e5 [( h* Z1 O
  230.         CE_Low();9 _$ X. @/ E/ h( y
  231.     while (temp == 0x00)        /* waste time until not busy */
    5 ^4 o) {; I1 v8 [8 {
  232.                 temp = SO;
    ) ~! S- n' A: T
  233.         CE_High();! I2 ]. F! k/ t  N8 C* A" J1 X
  234. }
    7 \& Q. }: v8 I$ p; H" w% b" t
  235. 6 Q  u2 ?; Z, P, A  g
  236. /************************************************************************/; T* n' O: i: g) A
  237. /* PROCEDURE: CE_High                                                                                                        */
    " Q2 q% |% y5 H/ o3 V( O
  238. /*                                                                                                                                                */' [9 D0 m8 Z+ g( ?% u( H9 _
  239. /* This procedure set CE = High.                                                                                */
    ; n  x  I2 O5 _6 r& T" L# Z& L
  240. /*                                                                                                                                                */' [  K8 ^/ j+ K7 C, B" u2 c
  241. /* Input:                                                                                                                                */
    , L4 t- z, p( K, e& ]
  242. /*                None                                                                                                                        */
    * _/ O- ?2 g4 H1 e0 O7 C- @! q7 o
  243. /*                                                                                                                                                */: V3 G% m* C4 m9 H1 S. j
  244. /* Output:                                                                                                                                */
    % U' V% z1 c: Y5 V% f0 d$ G# F# ^. B
  245. /*                CE                                                                                                                                */$ K- \* c; B0 a* j( O
  246. /*                                                                                                                                                */
    # j7 Q" Q8 ~& N5 f9 u+ {; b0 \! b
  247. /************************************************************************/7 M2 {6 S7 Z# v0 E6 W" |! V: v
  248. void CE_High() ; D' t& u* I. x! u3 U$ H( ?: j
  249. {
    7 q5 b* X4 C: J6 F) Y  y; a
  250.         CE = 1;                                /* set CE high */! x2 ^6 B; h1 j/ O
  251. }
    5 j. j! X2 \' f6 T. A3 K6 f

  252. ( c6 d6 _/ l" J, Z3 r
  253. /************************************************************************/8 C8 j2 A' Q$ L0 E. I
  254. /* PROCEDURE: CE_Low                                                                                                        */6 F; d: D7 D2 E  s9 Q# r% S
  255. /*                                                                                                                                                */
    , j% E( Z; B, _3 L+ ]
  256. /* This procedure drives the CE of the device to low.                                          */
    , X! u: M2 p; F
  257. /*                                                                                                                                                */( g) Y$ ?# U. M" Y* ~
  258. /* Input:                                                                                                                                */
    . c& M$ k+ t% u! o
  259. /*                None                                                                                                                        */" f. p( q8 K0 l8 F( m
  260. /*                                                                                                                                                */
    - l# ^) m7 [( ]1 K( \1 H1 f
  261. /* Output:                                                                                                                                */0 X, c& r& ?. {8 E: n* W; O
  262. /*                CE                                                                                                                                */
    . \# A3 ~$ v: Q7 j8 S
  263. /*                                                                                                                                                */
    * O2 }7 B  \% c) ]
  264. /************************************************************************/! L& S# ^9 b  ~4 S  @  {
  265. void CE_Low()
    * ]" o3 h. }4 U/ }
  266. {       
    8 B% i( P8 Y+ g" }; J+ O. S; J  `
  267.         CE = 0;                                /* clear CE low */
      E2 ]& e, y' ~( ~
  268. }
    7 N  R# B! |! p. c% |5 [* g3 F& N! P
  269. 6 o; |9 d; x+ a( U$ I% Y
  270. /************************************************************************/8 W3 Q, m& X+ W2 ?9 j) F
  271. /* PROCEDURE: Hold()                                                                                                        */2 e1 k2 i; o) }) Z/ ^* E! i
  272. /*                                                                                                                                                */1 U( U6 R; c* t" F8 ]
  273. /* This procedure clears the Hold pin to low.                                                        */4 q8 i% o/ \9 v; z( M( [6 ~' N
  274. /*                                                                                                                                                */8 R) t/ ~) @8 g$ D' o+ L
  275. /* Input:                                                                                                                                */3 V9 u6 Z+ j6 f; A4 v2 A  _
  276. /*                None                                                                                                                        */
    ( l5 }1 i/ f4 b# R5 j8 A! Q
  277. /*                                                                                                                                                *// t* ^5 f" D7 Q$ P
  278. /* Output:                                                                                                                                */
    " H/ B3 y% r3 c0 i: n$ A: Y
  279. /*                Hold                                                                                                                        */
      L5 S, T5 x1 \1 z# n4 i
  280. /************************************************************************/  x. b4 g! P- g8 ^8 ~
  281. void Hold_Low()) Q- h6 W4 ^* p2 q
  282. {
    % W( U2 }. H3 V# q& j8 F: t! i9 O
  283.         Hold = 0;                        /* clear Hold pin */
    ! i( T4 x/ C& S5 Q; W! ?8 I8 A
  284. }, Z4 J% [% F+ L! O+ G0 _1 l' n" z

  285. 5 M% @4 {, V4 {% s5 e; h
  286. /************************************************************************/3 x' q9 j) R* A
  287. /* PROCEDURE: Unhold()                                                                                                        */
    / I* L" h" H3 U9 N
  288. /*                                                                                                                                                */
    1 Q: L2 ?& H3 |  T$ F' @# a8 E
  289. /* This procedure sets the Hold pin to high.                                                        */! w8 B. n& I4 M- Y/ Q# s9 ^
  290. /*                                                                                                                                                */4 @5 l7 H' a$ p, T* k$ w
  291. /* Input:                                                                                                                                */
    * i3 ^7 Q1 ?9 F* C( d4 s, p3 K
  292. /*                None                                                                                                                        */
    , M7 j( }, f$ K; O5 @
  293. /*                                                                                                                                                */
      b6 N4 h7 X. f+ t
  294. /* Output:                                                                                                                                */
    5 p' f+ o5 ]7 w* ]+ s: M; v
  295. /*                Hold                                                                                                                        */* S- y* [( s% a9 |" l
  296. /************************************************************************/; U; n$ b, R" {
  297. void Unhold()
    3 p3 j/ r1 ?6 r2 W( c
  298. {4 z; W" L% E" k9 _$ K; y
  299.         Hold = 1;                        /* set Hold pin */2 d; Q5 i; a5 {, ^
  300. }/ b. M* C# n0 G& s( m- V

  301. 4 H/ Z# Y1 o( k4 R9 j# S4 w: k( y
  302. /************************************************************************/
    / C+ Q9 V# F; ]1 {
  303. /* PROCEDURE: WP()                                                                                                                */
    5 V5 Y. N. D& E- p5 ]5 p
  304. /*                                                                                                                                                */
    + t) F7 b% o0 I' O3 }- }
  305. /* This procedure clears the WP pin to low.                                                                */$ l5 M8 d. V9 E- U' ^
  306. /*                                                                                                                                                */
    ' |! v; ~  J9 `1 c& s! v
  307. /* Input:                                                                                                                                */
    ! o1 e& E2 o* ^9 ]8 b/ \0 O+ x
  308. /*                None                                                                                                                        */% n0 G1 M) I4 g5 `3 E! P' n4 J% N
  309. /*                                                                                                                                                */
    + O* F7 E! D; `# z) f
  310. /* Output:                                                                                                                                */
    * F& p3 P! r& |' N- w
  311. /*                WP                                                                                                                                */, }) _7 n5 E( R* L* K: S
  312. /************************************************************************/+ {( S5 V% d: F# Z/ e- `
  313. void WP_Low()
    3 Q( g1 ^' X9 I. I" c! q% L
  314. {  d! a2 s$ [9 K
  315.         WP = 0;                                /* clear WP pin */
    6 w& R" T7 K( S  c4 ]
  316. }
      K- G" Q$ {) g6 d- m: X( d

  317. # h+ W& {1 o( s2 Y# Z2 U0 }; w/ _
  318. /************************************************************************/
      B: J5 I; Y' C( P, f9 b: p
  319. /* PROCEDURE: UnWP()                                                                                                        */8 C; Y) F( I9 T; g2 A
  320. /*                                                                                                                                                */
    ! y) l. j' b4 i1 T# V
  321. /* This procedure sets the WP pin to high.                                                                */
    2 T2 p' W6 q4 S' ?' r- T
  322. /*                                                                                                                                                */
    + S! e; J3 B9 t) Z* A& ]
  323. /* Input:                                                                                                                                */
    % @# O. @1 e+ C
  324. /*                None                                                                                                                        */- }0 L* ~7 n: Z
  325. /*                                                                                                                                                */# [4 {, R5 T9 {
  326. /* Output:                                                                                                                                */
    6 Z( m! y7 M3 {. X' [; g( I
  327. /*                WP                                                                                                                                */
    : W+ P# x. G4 ]+ W* m
  328. /************************************************************************/* I9 I2 R# z4 ~, {: N
  329. void UnWP()) v' B, ]" w1 o# A/ [- t# y# j. {
  330. {
    , M4 l" C/ `4 s3 V
  331.         WP = 1;                                /* set WP pin */% c' S# o+ ?! t% @3 i
  332. }
    0 ~% k. X$ i9 B5 P

  333. . o7 Y* _. H6 {2 v) C
  334. /************************************************************************/* u4 g# e. _. l
  335. /* PROCEDURE: Read_Status_Register                                                                                */
      o' @! J' c* ]+ L
  336. /*                                                                                                                                                */
    9 r7 @+ i2 ~! w9 X4 |
  337. /* This procedure read the status register and returns the byte.                */
    2 m/ W1 x( Q- H0 w( Q% s$ L
  338. /*                                                                                                                                                */
    3 N; @+ e% i, P, \9 D
  339. /* Input:                                                                                                                                */4 J5 @  Q" X) b: v
  340. /*                None                                                                                                                        */! h+ Q0 ^9 D2 B- \
  341. /*                                                                                                                                                */
    ( a1 z8 v9 I; h; j7 m( i
  342. /* Returns:                                                                                                                                */
    $ G% p6 q* m$ y
  343. /*                byte                                                                                                                        */1 x1 D% z' \0 f9 [- g" k
  344. /************************************************************************/$ W: r# B7 g  z( u4 B& o
  345. unsigned char Read_Status_Register()
    : q. {5 q( X( R: P0 X3 u3 I. m* E
  346. {; f6 _/ `6 v* u) s
  347.         unsigned char byte = 0;% V* C" M1 f1 c3 Z1 V8 u
  348.         CE_Low();                                /* enable device */6 T3 l# O& b. m, e. i3 |6 R& {
  349.         Send_Byte(0x05);                /* send RDSR command */
    . R% G! e: |2 F4 y5 K2 c
  350.         byte = Get_Byte();                /* receive byte */+ A: P  }7 j' h7 O* c+ _# k- f9 Z6 \
  351.         CE_High();                                /* disable device *// P  h/ {# s' z, I& {
  352.         return byte;
    6 l' O  _5 `5 h. C( i. G1 a  U4 D
  353. }& j: K! c- O5 H. _  ~" V2 s( T
  354. 0 J2 P2 c, @- F) P
  355. /************************************************************************/) b( B1 }7 ?7 O* K
  356. /* PROCEDURE: EWSR                                                                                                                */
    7 d+ Y$ x! ^7 C: }# ~2 @5 L
  357. /*                                                                                                                                                */
    9 I6 c2 u( w' S9 ?* n( A( i
  358. /* This procedure Enables Write Status Register.                                                  */( }! A& }' l/ h" s) h
  359. /*                                                                                                                                                */
    8 Y# ^0 @4 ?2 h" Q* U5 h( h( [
  360. /* Input:                                                                                                                                */
    ( H- S' D3 p% w
  361. /*                None                                                                                                                        */* r- c5 C/ Q0 N6 J  G
  362. /*                                                                                                                                                */
    % ~0 e8 H* v% H- e% V+ Y3 R
  363. /* Returns:                                                                                                                                */. ^) E- x5 t. G  n1 Q
  364. /*                Nothing                                                                                                                        */* g4 z7 e$ e8 W$ K* M& M& \7 y
  365. /************************************************************************/
    7 B; i; W. a' v; x/ V( u9 A
  366. void EWSR()% }, ~# R9 z$ D" O. l' |
  367. {! g' _2 v0 l, D+ }6 o. R2 B( e
  368.         CE_Low();                                /* enable device */
    0 `/ e8 \( L. b8 |7 j" @
  369.         Send_Byte(0x50);                /* enable writing to the status register */. X9 G+ n% B( P" g, e
  370.         CE_High();                                /* disable device */) f4 x% }# i) u) `: ]! j7 k
  371. }$ A; z! P& n! c5 D

  372. 6 m; N. ?% |  I1 E2 a" Q; H4 _
  373. /************************************************************************/+ K7 ^/ r1 {& i0 Y" n; J- A1 K
  374. /* PROCEDURE: WRSR                                                                                                                */
    5 e; E' H) M. q! z/ Z
  375. /*                                                                                                                                                */
      O) v. {4 w7 W6 `2 V
  376. /* This procedure writes a byte to the Status Register.                                        */
    ) Y4 {8 h) F+ n/ [
  377. /*                                                                                                                                                */
    9 _. L" ]1 `4 T  W
  378. /* Input:                                                                                                                                */
    + w  E. T$ h7 U/ [
  379. /*                byte                                                                                                                        */
    3 U' F! `$ W; j
  380. /*                                                                                                                                                */) ^  P$ Z8 O! @6 ~3 i8 B2 E& j9 w
  381. /* Returns:                                                                                                                                */% z' K7 {. {- O1 }
  382. /*                Nothing                                                                                                                        */
    ! X9 a) z* u; ^, _& K
  383. /************************************************************************/
    5 V  m" n; |1 R+ F: t0 k0 h. d
  384. void WRSR(byte)3 _* q* B' u7 l+ k2 K
  385. {
    $ W4 s6 n5 v' d5 j7 s7 h* L9 |
  386.         CE_Low();                                /* enable device */# x$ T1 d; |4 f, c$ v& S+ j: {/ p
  387.         Send_Byte(0x01);                /* select write to status register */! }; l) Z) |$ l" h& J# k/ s
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    + d: ]4 I/ [/ R: f4 n
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    2 Y/ o: w9 h3 t; A6 Q7 ]: |
  390.         CE_High();                                /* disable the device */7 w3 ~! z) _% X' L/ o6 `/ S
  391. }& L6 F, Z' v& u, k4 A# f8 Z
  392. 3 Z2 G1 p" X& i, y
  393. /************************************************************************/! h- f1 X5 F+ L& i
  394. /* PROCEDURE: WREN                                                                                                                */
    $ @1 M3 f+ X8 s7 A6 O1 I% W5 M7 s
  395. /*                                                                                                                                                */2 d8 R$ e! T1 _2 k
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */- x! x9 Z- I! d6 f' A+ G
  397. /* to Enables Write Status Register.                                                                        */
    9 A, f3 k- B& I% t9 a8 o3 i
  398. /*                                                                                                                                                */) n2 A8 E# D6 Y
  399. /* Input:                                                                                                                                */
    - \; T  C+ H+ S0 p; J3 P* B% r
  400. /*                None                                                                                                                        */
    ( g" z5 f6 p7 A
  401. /*                                                                                                                                                */( t! S. e3 }* }: ?$ I
  402. /* Returns:                                                                                                                                */. a( t: ~' M4 ^2 c8 o7 S; N' r
  403. /*                Nothing                                                                                                                        */
    1 \$ o$ D! N' o0 T
  404. /************************************************************************/: ^3 K& n8 X( N' L
  405. void WREN()
    # p8 x- K, c8 v# `2 w: r6 Y
  406. {
    + x  J. f" i% m+ n5 Z2 [& k% {' [9 s8 @
  407.         CE_Low();                                /* enable device */
      l5 y/ e* E' R/ q! a
  408.         Send_Byte(0x06);                /* send WREN command */
    2 K# I8 a$ p% k+ A* i1 c) m
  409.         CE_High();                                /* disable device */0 d" [4 n" c$ |( v8 N0 T! ]5 ?
  410. }
    7 u* h( u; u1 T4 n1 y
  411. 8 |% S( {! g$ V. {6 h7 [+ j6 S
  412. /************************************************************************/+ g( G1 _" Y0 ?
  413. /* PROCEDURE: WRDI                                                                                                                */9 c8 {- q/ K  o$ K) k! e9 @7 U
  414. /*                                                                                                                                                */
    " P: D! E  H/ K: H  e4 N& k3 K* K( q
  415. /* This procedure disables the Write Enable Latch.                                                */
    : I# s) h7 N: L8 ?" }
  416. /*                                                                                                                                                */
    " w9 y0 T  K* T% ]
  417. /* Input:                                                                                                                                */
    % \& {% N, j3 i9 Y& \# r% ?
  418. /*                None                                                                                                                        */3 I6 R" ]- ?4 Z: t% l  G2 \
  419. /*                                                                                                                                                *// @- T6 h2 C* F) d
  420. /* Returns:                                                                                                                                */
    # y- E. L& u- T, O
  421. /*                Nothing                                                                                                                        */
    / j, L1 k* T" ~& n0 z( O; o2 \: D8 d* x
  422. /************************************************************************/
    7 Y8 w5 H, p" O% \- o5 ?* ~3 `; K
  423. void WRDI()% L6 k# Q4 z( \3 x+ L
  424. {5 G4 y* }3 d% F# F5 U% |
  425.         CE_Low();                                /* enable device */
    - t# q2 M3 A$ {# ^6 B) b' Y1 n# O; r
  426.         Send_Byte(0x04);                /* send WRDI command */. P/ i$ u1 B" D! M+ A+ M8 q
  427.         CE_High();                                /* disable device */
    # V# [% o9 I+ o* O, G
  428. }# P0 G5 p+ X( y# w6 f) L

  429. 0 w. L+ {( k7 @7 v5 h, }' H! e" i$ L
  430. /************************************************************************/
    ! j1 ]& P! m2 X0 G# s' Q9 Q
  431. /* PROCEDURE: EBSY                                                                                                                */
    ' E8 y$ p1 Z( }6 g# g) i3 q- t: K  J
  432. /*                                                                                                                                                */1 I4 x) Y: b9 u; T$ w
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */4 g* K' P; G/ M& y& Z
  434. /* programming.                                                                                                                        */
    ! G3 M9 S- V* A& w
  435. /*                                                                                                                                                */
    3 Y5 ?: ~/ ^# k# o* |8 B3 P
  436. /* Input:                                                                                                                                */
    * P5 E# m9 ?+ J3 h* z
  437. /*                None                                                                                                                        */+ k% U4 [. [/ _
  438. /*                                                                                                                                                */
      k) y/ F# y" z! ]+ N7 V
  439. /* Returns:                                                                                                                                */
    : w. W* j/ U7 E9 [% A6 K& e
  440. /*                Nothing                                                                                                                        */: Y! ^6 P  g$ {/ F  i" q
  441. /************************************************************************/( O2 _; r6 h$ `3 y/ y, J
  442. void EBSY()
    2 w2 O# c1 J9 A+ m; ^" V% f2 ?
  443. {
    + V; x8 S+ s* J" P/ B; J% U
  444.         CE_Low();                                /* enable device */
    ) _0 X) t& B3 n1 F
  445.         Send_Byte(0x70);                /* send EBSY command */
    * p9 q" C  Y9 B0 D- w6 K2 d$ l
  446.         CE_High();                                /* disable device */
    " z6 k1 Y+ u( n# M
  447. }8 E$ J1 Y5 P: V, X6 h0 g

  448. 6 L7 W; ~# W1 V2 p1 ?/ x0 }4 ?  x
  449. /************************************************************************/" M5 S! ^8 i/ J- j( {, I( |) f
  450. /* PROCEDURE: DBSY                                                                                                                */
    % p9 h  G( q- I, H
  451. /*                                                                                                                                                */
    2 ?$ w# |6 N3 c
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    / }  A( }3 R' l& o2 n% j
  453. /* programming.                                                                                                                        */
    ' ^* f6 y4 [% [" G; e
  454. /*                                                                                                                                                */
    " k1 t2 @& o; a+ c
  455. /* Input:                                                                                                                                */& b& R# x$ u! C+ ^& x6 O! u5 B9 P; M, K
  456. /*                None                                                                                                                        */  Z. ~2 B8 t7 j3 A( k6 y
  457. /*                                                                                                                                                */
    $ K5 K" @$ A/ G/ Q( d( X, R& ?
  458. /* Returns:                                                                                                                                */5 X3 u$ h* F2 r* X- D  P
  459. /*                Nothing                                                                                                                        */1 s. F; W3 o) l, S4 s& [" R9 i
  460. /************************************************************************/  |( ~9 Q$ f5 ]  J
  461. void DBSY()
    % Z; u) B3 \5 I' e
  462. {* S& C* F. o  F) D' W
  463.         CE_Low();                                /* enable device *// `' Z. t; v8 |
  464.         Send_Byte(0x80);                /* send DBSY command */6 {! p3 B8 S6 {; D% U6 o  W
  465.         CE_High();                                /* disable device */
    $ ^; q+ |! }8 q
  466. }
    $ e7 U; |2 G( @9 s; W% x
  467. : r. o0 N0 ^" k) R  Q/ X9 ?& @; U
  468. /************************************************************************/
    . [( c' U1 m7 Z3 o
  469. /* PROCEDURE: Read_ID                                                                                                        */
    / ^" g! |8 W" s+ L3 C% P
  470. /*                                                                                                                                                */* O) L. K8 M- H& F! h. P. U
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */$ s" A3 |8 t! m; T* r- V4 {9 l
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */% H- {7 d2 P- f/ k) x  y" [
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    ! z6 L7 A2 y; S1 r: b
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    ( a4 {% [, b- w: d; n# ~# w
  475. /* first.  Please see the product datasheet for details.  Returns ID in */2 S* d+ ?7 a4 S& {5 @! J$ a
  476. /* variable byte.                                                                                                                */6 K( t2 d4 M: t& z
  477. /*                                                                                                                                                */# m$ a3 [+ S, E. }8 x
  478. /* Input:                                                                                                                                */
    1 G# Y, U% P4 C1 i9 B' e+ C; Z% D
  479. /*                ID_addr                                                                                                                        */
    ) \8 _0 O" M2 _: |
  480. /*                                                                                                                                                */# r# Z; }. E! `3 A" N* N
  481. /* Returns:                                                                                                                                */0 b# t/ X4 X$ v  q
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */& M, g3 f# f) x4 E: X( T
  483. /*                                                                                                                                                */
    5 E( p% L/ n, l% j( \/ [
  484. /************************************************************************/
    # d' \; v) [2 U9 Y5 r& Q" u4 W0 x
  485. unsigned char Read_ID(ID_addr)1 [: m* r& F' y
  486. {- ^; n  p- t; @( R) X) e
  487.         unsigned char byte;
    : e) r  y1 n. [! C* k
  488.         CE_Low();                                /* enable device */  a+ p2 e$ {2 H% P: J0 W* z% O
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */2 {2 C* K4 H/ u: j3 D
  490.     Send_Byte(0x00);                /* send address */5 s" `, h- E) V+ H/ Z3 R3 [$ g" H
  491.         Send_Byte(0x00);                /* send address */
    % W9 f. k0 s. d& y
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */7 _3 o) j  j( Y8 K( ]! l. [
  493.         byte = Get_Byte();                /* receive byte */4 A3 ~  k% Z& T+ z: M  C+ @" p/ y
  494.         CE_High();                                /* disable device */
    - r& l& N' O4 @
  495.         return byte;
    0 O" w$ m$ H2 M- y" P! k! }
  496. }, S  X" V: l0 {  g& ~* c$ y6 b

  497. ) Q2 j3 I* W/ N! A' I
  498. /************************************************************************/3 {  `7 b& \' j1 R) S1 d
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */! E' m+ \5 u% O
  500. /*                                                                                                                                                */
    , Q, j; d4 }3 O7 J+ R" p  k7 K( s
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */4 n- L8 m$ d8 m$ h4 F
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */& n* Q) c$ W* A
  503. /* Please see the product datasheet for details.                                                  */0 H! M/ c5 D6 T6 `: c4 t
  504. /*                                                                                                                                                */
    ( l: P4 S( [* M0 k. y
  505. /* Input:                                                                                                                                */
      }) O1 C' v+ S# @
  506. /*                None                                                                                                                        */
    & l. W! y+ T% N$ A1 b) p) A  i
  507. /*                                                                                                                                                */5 G; Y; S/ x/ q7 o$ Z$ z5 r% }8 b: u
  508. /* Returns:                                                                                                                                */
    1 w( w3 X8 d0 z5 s$ n; s
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */, q: ?, ^- b3 T( {0 P& z
  510. /*                 and Device ID (8Eh)                                                                                        */
    & H( g& a4 V" h! m, Q
  511. /*                                                                                                                                                */
    1 z" e! ]4 O5 s
  512. /************************************************************************/( ]; E- J6 F. y
  513. unsigned long Jedec_ID_Read() " f* v8 O* R/ I7 \- f
  514. {$ @; n4 I: k% a9 L* P* j
  515.         unsigned long temp;( U' P/ }1 V$ T' \! Q/ s* d
  516.         . Z# m, i, e/ T: c. ^. w
  517.         temp = 0;1 p: m' Q# `! l' A
  518. ' D) t( H9 u( @: T7 C9 z7 I
  519.         CE_Low();                                        /* enable device */
    - l! v# g% J- Y) [3 B; G
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    ! ]2 O6 f. Z, }9 {$ S! o; M( l% i
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    . J3 c. Z% Y# T5 y& @6 n, L
  522.         temp = (temp | Get_Byte()) << 8;        # t' P; b2 Z5 H6 J6 D2 c, w9 v
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    + U( w6 Q- Z# n1 k' l
  524.         CE_High();                                                        /* disable device */
    9 ^0 E- q8 Q. A) \" q6 i

  525. 2 j# H5 g6 @1 J4 J7 g
  526.         return temp;
    : H4 l& Z' y# a7 V; e
  527. }6 z" l+ u2 R: F) X' ^
  528.   i% e! r5 f4 ^! X# H$ o
  529. /************************************************************************/
    0 O& A& L0 P, p. D; z, _  p% V
  530. /* PROCEDURE:        Read                                                                                                        */
    / o3 y8 [" Y. h' r: B
  531. /*                                                                                                                                                */                - T) |$ ?) s, e
  532. /* This procedure reads one address of the device.  It will return the         */
    0 K2 \& Z" N8 R5 N
  533. /* byte read in variable byte.                                                                                        */( c) U; Q. G) H
  534. /*                                                                                                                                                */- i) `) ^" U7 t
  535. /*                                                                                                                                                */
    7 k& F4 w# t) J/ X7 ~1 |4 c7 M
  536. /*                                                                                                                                                */
    ' T9 M/ y: j5 Z+ D* l
  537. /* Input:                                                                                                                                */: o- c/ ]. A7 F# o4 \, u; @' V
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    0 U' c# ~# P+ _: Q* Q
  539. /*                                                                                                                                      */
    3 W( Q8 z4 o2 I* U: T
  540. /*                                                                                                                                                */
    - ]* y0 `% L4 m$ o
  541. /* Returns:                                                                                                                                */
    4 x* r7 P/ j+ N5 E' W, c
  542. /*                byte                                                                                                                        */
    : h/ X5 z! s: `3 {* p  |- J
  543. /*                                                                                                                                                */5 z" U* h  [* R8 A2 }
  544. /************************************************************************/; I1 [/ v, A. d; f" j; a
  545. unsigned char Read(unsigned long Dst)
    : P' g4 w" G1 k+ j) U: [& a
  546. {- Z% e3 E% V: s9 E
  547.         unsigned char byte = 0;        : t2 |1 _7 b: F, \2 ~
  548. 8 H! P/ m. E% I) q* K) x' ~9 Z
  549.         CE_Low();                                /* enable device */
    4 Q4 @8 Y: f4 C5 v
  550.         Send_Byte(0x03);                 /* read command */
    2 y9 J9 x" J$ d& U6 S$ O: H
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    4 O7 k& p5 ^6 p0 Y. h2 u
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));; s- W( o: T3 F# d( E; l
  553.         Send_Byte(Dst & 0xFF);' ^7 ^; F$ r  C* h4 j% D- _
  554.         byte = Get_Byte();- A' ^3 n4 `$ U% G" G
  555.         CE_High();                                /* disable device */4 t. q% E8 L' Z! F
  556.         return byte;                        /* return one byte read */
    " D9 ?# m3 ^# l" w* w
  557. }
    5 |8 G7 }$ p8 [( ]& o1 Y) C% y9 u
  558. % |$ W! ], W* j  |+ c3 a( F
  559. /************************************************************************/: k8 c9 f, L- [
  560. /* PROCEDURE:        Read_Cont                                                                                                */8 Q+ B$ C$ N  d( j- @+ X0 B
  561. /*                                                                                                                                                */                ( f: v* S- ?2 z2 v
  562. /* This procedure reads multiple addresses of the device and stores                */
    : ^! f2 ^" x3 k- n+ p2 I7 A& v& N& Z: t
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/. t5 E* d7 `1 T* D: U! A: {4 m- P
  564. /*                                                                                                                                                */
    8 s2 E) w  e5 d% o# {
  565. /* Input:                                                                                                                                */0 Y$ E7 n0 N  M0 z$ w* D- P: E$ ^
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    $ }, ^) R8 ~2 o0 \' v7 V! z
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */4 U( `& N4 s. b- D* ?4 Z
  568. /*                                                                                                                                                */" Q' w& t+ U* U8 P/ T" Q- a; Y
  569. /* Returns:                                                                                                                                */
    * e: e* b1 }* u% E# T( m( A
  570. /*                Nothing                                                                                                                        */
    . @1 e& R, V; d5 |, e
  571. /*                                                                                                                                                */
    : W  p% }9 S: I, L
  572. /************************************************************************/. i+ t3 f# h0 Q4 T
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    6 O* F6 h! }( u% H8 x/ @4 D
  574. {# }! a7 N% @! G3 i( Q" Y" }6 E9 O# m; ]
  575.         unsigned long i = 0;
    7 i+ b: W6 \0 u7 |
  576.         CE_Low();                                        /* enable device */
    3 L2 K' {# g2 k1 O4 f
  577.         Send_Byte(0x03);                         /* read command */
    6 R! w$ ?& z3 c' j: E9 Q
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */$ L% A0 E/ x5 x0 ^# S: A: C1 k
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));" m  S: i- Z8 w
  580.         Send_Byte(Dst & 0xFF);* i8 J+ P% G6 D; S
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    ) g, _& V0 p1 f
  582.         {
    + t- }2 v! Z. o" M+ T; m
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    0 C0 C+ v) q; p4 ^. d8 B- P
  584.         }
    ' w2 _: g6 |2 F! R! Y2 @( l9 e
  585.         CE_High();                                        /* disable device */
    4 h+ z1 K3 U: l) C4 Q  @

  586. 9 T) [) _$ n# u: k9 g
  587. }
    ! Y$ O8 Y, g* a0 P
  588. & }$ L  I2 N( Q2 g
  589. /************************************************************************/& b: T. O+ c2 }4 e* ^+ w+ X
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */# l- N  P& H4 D9 J
  591. /*                                                                                                                                                */               
    + b: d0 H2 M8 t( m, L1 W: A$ T- C
  592. /* This procedure reads one address of the device.  It will return the         */% ^: k7 x5 r2 @9 Q
  593. /* byte read in variable byte.                                                                                        */
    2 b, v: p8 R8 s2 Z/ W. j2 `
  594. /*                                                                                                                                                */# z- w- c4 m) q
  595. /*                                                                                                                                                */" ~3 a: Z- Y5 \2 E5 M
  596. /*                                                                                                                                                */, P9 y7 D6 s' p; O
  597. /* Input:                                                                                                                                */
    . e  c( j7 }0 D- X- f
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */2 f7 |: c8 |5 ^: H0 u: U
  599. /*                                                                                                                                      */& b9 z: u8 e# H" t# N  U! w7 S4 J
  600. /*                                                                                                                                                */- ?. C0 p( n) [2 q
  601. /* Returns:                                                                                                                                */) D9 W- ^+ w  P& p5 ]6 `0 h5 W
  602. /*                byte                                                                                                                        */) _+ r1 Q, ^3 x
  603. /*                                                                                                                                                */* F- {9 J+ l% P0 }+ q
  604. /************************************************************************/
    0 z% E6 I1 y9 Q2 h! H+ d
  605. unsigned char HighSpeed_Read(unsigned long Dst) ' @: D& t3 W+ s( c$ b6 z0 @
  606. {# ?/ a9 u1 n+ P3 J4 k8 f2 L, Y
  607.         unsigned char byte = 0;       
    ' W, @8 Z; m$ P4 u' |0 d8 H

  608. " h3 g5 h6 |5 n1 S. P
  609.         CE_Low();                                /* enable device */
    ; M$ O$ E* F( j; y
  610.         Send_Byte(0x0B);                 /* read command */& ~! l3 L3 G. O+ ~/ h
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */' Z2 [+ K  ^1 U2 w% f
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    * [0 _7 F/ i  E- s7 T2 w
  613.         Send_Byte(Dst & 0xFF);
    $ Y3 e# ~# ]1 P- x( n9 ~
  614.         Send_Byte(0xFF);                /*dummy byte*/
    6 N) B  w, O; b# Q) R
  615.         byte = Get_Byte();7 n5 I# \, n; o! s
  616.         CE_High();                                /* disable device */
    / p4 j$ X' G  w3 O/ \2 s; O$ B
  617.         return byte;                        /* return one byte read */
    4 j" N( ^4 \0 |6 F( s
  618. }9 ^! q8 f0 ^5 V4 J& t3 l
  619. . [7 K# M$ H' b3 ~
  620. /************************************************************************/' c$ _, o+ U5 v
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    / A7 ?9 Y% l' O/ M9 A
  622. /*                                                                                                                                                */               
    - V3 k. {0 T0 U. G2 O& W6 ?9 R
  623. /* This procedure reads multiple addresses of the device and stores                */- C/ q8 D6 G& J; ?$ h
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/( e( P) C% Z3 k
  625. /*                                                                                                                                                */
    * n* E0 K1 ?/ F& m, }+ R
  626. /* Input:                                                                                                                                */
    ( s5 B6 d% Y1 t* r( U3 {& F
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */. C( v* ^# A) W; L& r- b/ p! W
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */, Y. i7 \" Q6 W7 I: n
  629. /*                                                                                                                                                */, G! s. f, j  i
  630. /* Returns:                                                                                                                                */
    6 s, j. q, V# w2 P
  631. /*                Nothing                                                                                                                        */
    , m& C2 _( A5 A0 z9 ]6 ]
  632. /*                                                                                                                                                */1 H; }( g  H9 t3 U/ T6 I# J
  633. /************************************************************************/3 s& N5 o+ r0 G% a% `
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    + b0 Z  b1 Y- O3 D" H
  635. {- C8 B6 Q8 `" C( s% O$ x, R) l  {+ A
  636.         unsigned long i = 0;
    , R8 h. q) |) b& T' o! t" ^% j- c
  637.         CE_Low();                                        /* enable device */
    # d5 C# j) H' u2 u. q
  638.         Send_Byte(0x0B);                         /* read command */
    4 x* o9 C, f  @" n
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */0 x* x( M6 w; d
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));" n( _5 D8 a+ A  r! ]
  641.         Send_Byte(Dst & 0xFF);
    6 A, I, V' q; e6 N1 \  r
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    4 N2 Y0 x' y! I' A; E' S
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
      U6 A8 Y3 v3 \
  644.         {! I) s& [# N/ n: N
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */. T8 U! w# y& y+ A# P/ T
  646.         }
    . c6 q/ L# R. m5 t# A1 W4 Y# S
  647.         CE_High();                                /* disable device */# Y( V& s: k" h- A5 l3 P) D
  648. }5 d+ u; `6 W1 _# u1 e" o, `: r

  649. * u5 X: O7 ?$ Z6 @6 S
  650. /************************************************************************/
    6 Y  M& k0 U3 h6 _3 k4 |& @$ v$ O
  651. /* PROCEDURE:        Byte_Program                                                                                        */2 ^' o# j% t- g: _6 H9 Q8 f) H! F
  652. /*                                                                                                                                                */
    " N& e/ X0 q9 U; [
  653. /* This procedure programs one address of the device.                                        */! M' E2 W  }( p$ R3 t; q4 g1 m1 P
  654. /* Assumption:  Address being programmed is already erased and is NOT        */$ o& }! V# D' q4 |
  655. /* block protected.                                                                                                                */, X1 I- g4 U* U; ^& F
  656. /*                                                                                                                                                */9 |& \/ ^8 t3 a" r
  657. /*                                                                                                                                                *// N+ u4 g7 l5 c
  658. /*                                                                                                                                                */8 K: N' a( H" f: }* s
  659. /* Input:                                                                                                                                */* c# ?. o# J8 e8 T1 D% u/ @
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : R% C( Q% O% O3 z
  661. /*                byte:                byte to be programmed                                                                */
    5 _* }% A% ~1 \# ~9 J) m8 d0 d6 U
  662. /*                                                                                                                                      */9 X! [( L3 E( g( F$ b0 U6 h
  663. /*                                                                                                                                                */1 N# s1 D5 A/ {8 u2 P0 y4 ?& }
  664. /* Returns:                                                                                                                                */- Y, u+ f* v! F8 {5 P
  665. /*                Nothing                                                                                                                        */' b8 k6 {0 T4 k8 u. v- ~6 j
  666. /*                                                                                                                                                */
    0 l, t, @% U5 q% G$ g
  667. /************************************************************************/' C- N; E, b1 j" z; v
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    - ?2 L/ N' \1 C0 {0 }" ]' c5 _
  669. {
    4 y; `& ?6 _/ Q5 g
  670.         CE_Low();                                        /* enable device */: \* y" h* \# W& [- n
  671.         Send_Byte(0x02);                         /* send Byte Program command */+ P* T' K1 N6 j- E, j# G4 Y7 a, U
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */- p* D0 L  U( E6 E3 J
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));% Q9 O5 Q7 h/ D/ B0 _7 l6 E
  674.         Send_Byte(Dst & 0xFF);
    % s9 f$ W: A8 I, H3 H% R7 c" n( e
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    3 x' M! h$ E/ @; n1 y* m. C
  676.         CE_High();                                        /* disable device */( ~* r9 P* T  d; I9 Y! a
  677. }
    / r# y2 K" t. {$ {

  678. ( l* m. k( x8 V- G
  679. /************************************************************************/; S& `0 [2 E! D1 ?/ `
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    2 s  ?6 u% [5 j& _6 z
  681. /*                                                                                                                                                */, ~, e. }1 m" X' v2 {& C/ |
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/1 b1 n3 w# a% S+ L  n
  683. /* the device:  1st data byte will be programmed into the initial                 */
    & n: }. x) G- }
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */" V$ s& n0 V6 v( @
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */: V- M  c2 @7 T! m6 l
  686. /* is used to to start the AAI process.  It should be followed by                 */
    * F* o' n) A0 U$ h* _
  687. /* Auto_Add_IncB.                                                                                                                */6 J9 r) \0 m7 Y6 L2 ~" R9 @
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    + u0 m3 s2 ]8 |: O6 I6 h- r
  689. /*                                block protected.                                                                                */
    - E: y0 e7 ~8 w: w. R) O2 n
  690. /*                                                                                                                                                */( @9 m& S6 j1 s+ N( H
  691. /*                                                                                                                                                */
    9 j/ s( g' A( \& {
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */9 t8 P* \/ {4 [6 C& M9 T, M$ ]
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */, r7 O7 p4 k2 Z  s. C; t; ?* I
  694. /*         unless AAI is programming the last address or last address of                */
    + t5 c' p& G0 W% u/ Z5 i8 W
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    4 ]7 \) x" l* F! A
  696. /*                                                                                                                                                */9 R3 C7 V. e; v1 H% l
  697. /* Input:                                                                                                                                */! ?8 h0 Q( Z/ h) z' I7 ]& ^2 `
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */, u: J1 b  P$ x! ?- \$ N
  699. /*                byte1:                1st byte to be programmed                                                        */
    . c& g# x( s1 u* }3 G, S
  700. /*      byte1:                2nd byte to be programmed                                                        */
    ; k2 w' ]! I  W5 V  @; Z
  701. /*                                                                                                                                                */3 q% F7 _8 w7 t) `6 o3 I
  702. /* Returns:                                                                                                                                */  b% Y+ z9 n" a! g* B
  703. /*                Nothing                                                                                                                        */* M) L; B% a# H+ J5 [/ u8 a
  704. /*                                                                                                                                                */  \  r5 p" M( L2 ?  x( ]) _
  705. /************************************************************************/( R2 m% s: l2 ~& l! N0 I
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)7 o4 P9 U7 p  R
  707. {
      q: e. ^' T5 v6 m+ W0 H
  708.         CE_Low();                                        /* enable device */7 c! y2 n/ B3 F' W& p
  709.         Send_Byte(0xAD);                        /* send AAI command */
    6 ^. e8 i- m! u* {
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */% e% S7 p5 v3 c6 o9 H
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));& P7 [4 B; Z& f9 f  x
  712.         Send_Byte(Dst & 0xFF);$ A6 N( z9 P( F! }
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    ) E4 K, x4 U2 Z7 W7 R8 \4 ~
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */6 }( s' p/ ]0 ~8 G
  715.         CE_High();                                        /* disable device */
    & Y, P! g7 b% G& ~
  716. }
    ! e+ `! S- \0 N6 f4 o, }

  717. . H+ C( M$ {1 N" W% Q
  718. /************************************************************************/
    ( i& c& q+ y" ~1 ?2 W$ r
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    - D- [5 b9 L7 V8 o3 T4 L6 ]
  720. /*                                                                                                                                                */7 R2 }( \9 X; ~. d: U7 L
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/& m& O, w3 x6 `) V) s6 `
  722. /* the device:  1st data byte will be programmed into the initial                 */
    # Q4 [5 w( ~, Z, g  d
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    / f$ j; @' K( B+ N
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    8 H- S2 W( u9 U; ], f
  725. /* is used after Auto_Address_IncA.                                                                                */
    * T/ a# }- S3 }7 L$ @% |9 t' @
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    2 P* B/ }8 u3 g3 f% G/ X* B
  727. /*                                block protected.                                                                                */
    9 v( E5 D$ f/ q7 s" L0 g
  728. /*                                                                                                                                                */4 e4 e7 s, X+ X2 H" |6 e
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    * l& [+ D, G2 T3 k# w, j
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    , \* E$ L/ e; Q8 W. E
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */5 j4 j" c% r3 ?( X2 l
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    8 u$ m5 m- D; Z5 ~9 a" W7 L( J- c2 R3 o
  733. /*         last address of unprotected block, which automatically exits                 */' y& L0 s  e8 Z( H. H. H6 @
  734. /*         AAI mode.                                                                                                                        */
    # i' g+ o& b$ {/ J2 q9 E
  735. /*                                                                                                                                                */. }: y/ ^: y3 c+ o
  736. /* Input:                                                                                                                                */
    % P; b3 A8 M, d% f) ~4 J$ L) A2 L5 S
  737. /*                                                                                                                                                */, \; d" S* w, o. E1 \! e
  738. /*                byte1:                1st byte to be programmed                                                        */
    . ?+ ~  Z7 D  I8 U; M3 _& p
  739. /*                byte2:                2nd byte to be programmed                                                        */
    / Y) O$ y1 \! g9 K. P
  740. /*                                                                                                                                      */  i* u$ F" K2 v+ h* F
  741. /*                                                                                                                                                */: ?4 v) X, w* j1 J5 t6 N. _0 ~- W. e
  742. /* Returns:                                                                                                                                */
    , M: I" J7 {1 b( Y
  743. /*                Nothing                                                                                                                        */
    $ T) z: U+ n% u2 z5 M
  744. /*                                                                                                                                                */
    0 I( L3 G2 A) {+ O
  745. /************************************************************************/7 f: T, U$ V+ `% _* o
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)) z6 g4 d9 s: h- A8 L$ ~3 S/ }
  747. {
    8 ?8 ~% u6 Z  {3 I7 c' o
  748.         CE_Low();                                        /* enable device */
      z0 y; Y; f$ S9 N( r4 T
  749.         Send_Byte(0xAD);                        /* send AAI command */
    9 \8 a9 D  `. Y4 v
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    4 d' V; L0 ?  d- S# K7 i0 E: L3 `
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    5 ?6 o6 E' u/ ?% o, o
  752.         CE_High();                                        /* disable device */+ `" b  H- n" C
  753. }
    6 |$ J3 u4 f4 q' C3 m) r

  754. ) X$ Z. R9 l! |
  755. /************************************************************************/  D: K2 v- M: L( l
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */7 i1 S" a, J( t8 Q* \
  757. /*                                                                                                                                                */, G" r; E) C# w( \, P/ `8 m6 }
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    ( s* d, T; T7 R/ b9 L
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */% F7 W6 |4 ~2 b9 v+ T2 t! D) L% I$ w
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    % C1 J% M% X( J! o" Q3 s
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */% S' y. m7 t. q5 V$ v; W
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    * L* c; ^' y$ J, }: `/ ^
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */  z5 H8 j" n+ ^# `) Q# B
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    ! M* h8 X, v$ ^3 ]- Z' c+ [. b7 K6 @
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    $ F& h* D/ B& X4 a5 Z1 r  N
  766. /*                                block protected.                                                                                */8 Q: }% j, @* I/ \- {% {/ h( {
  767. /*                                                                                                                                                */$ A. T/ ]: p$ A8 U
  768. /*                                                                                                                                                */
    & Q: c1 Y' l9 m  ^$ b% e- s) f
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    2 g$ Z( q: ?# E: h
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    9 I: L) r  s5 C
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */! A& r, A1 x& o0 [) l
  772. /*          to exit AAI mode unless AAI is programming the last address or                */4 E& K5 c2 p" \5 {/ }( b' {
  773. /*         last address of unprotected block, which automatically exits                 */
    / x5 {' P/ D( D- \; ~
  774. /*         AAI mode.                                                                                                                        */
    ( U9 T) b0 M1 t/ Q/ L! z8 K! l. T: i
  775. /*                                                                                                                                                */
    , \: }& }6 i. l2 u
  776. /* Input:                                                                                                                                */* p$ B5 g9 Y. k  o& r! ?/ b
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + _3 o1 i4 X' {8 [+ q2 }$ O; Z
  778. /*                byte1:                1st byte to be programmed                                                        */5 R+ w# `- S: N% N
  779. /*      byte1:                2nd byte to be programmed                                                        */0 X+ Y' ~8 c0 z
  780. /*                                                                                                                                                */
    4 ~$ H+ c  t! G/ F8 g% Z- L8 n
  781. /* Returns:                                                                                                                                */
    * m8 H, K# k; z$ W5 W% ?* s( K, N
  782. /*                Nothing                                                                                                                        */
    5 o0 h; |$ f8 g% p! Z7 h$ p; c7 p
  783. /*                                                                                                                                                *// A  w& E; K" `
  784. /************************************************************************/& ~* z* O9 y7 B0 b! H, [! A
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    4 ~2 }5 W/ ?/ R9 T, B
  786. {
    9 q  z4 }. b! d" o9 a: e5 `2 r3 z
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    9 T( S  @/ G. A% K. z- S

  788. 5 D3 D3 r1 }3 z+ d
  789.         CE_Low();                                        /* enable device */* m% i1 v; p7 |
  790.         Send_Byte(0xAD);                        /* send AAI command */
    ; L1 V2 K  D4 T
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    4 m- E" E0 `4 n' ?5 i
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));# x! ?( X  s8 g/ K: Y9 D
  793.         Send_Byte(Dst & 0xFF);" b/ D( F. i! L5 r: {5 p& w9 c
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    4 G" s5 D" @+ i, Q  J
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    : |" E0 _% u' h" I' v
  796.         CE_High();                                        /* disable device */
    ' b4 @# m  v4 e7 {
  797.         : N8 o9 n8 p7 K+ U3 ?  M
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */% {' t+ {( Z$ Z, h8 P4 J  N

  799. ! I7 O9 Z  i) y$ ?% h& K
  800. }  y+ K, ]4 X. C- n

  801. $ t, U3 m' m( i" b
  802. /************************************************************************/# N) h+ B9 ~4 a/ l# I/ Z( \
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    $ M' E% I+ k6 q% M( B
  804. /*                                                                                                                                                */8 [. D* K1 j( r0 S/ j% E
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    / q  C" h# s6 r
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */# {5 g4 D4 d! L  z9 r
  807. /* AAI programmming is completed.  It programs consecutive addresses of */# b- x& y$ \2 Y1 c) f, z
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    6 C! D6 h! x5 [& t6 j$ W
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */. k5 M/ i2 v* L
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */7 [! B9 A5 x$ Q) q
  811. /* used after Auto_Address_IncA.                                                                                */% V' v4 b. O3 J! [3 \) A* Y2 w
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    ! E3 h; S$ G5 p; ~
  813. /*                                block protected.                                                                                */3 X+ n" S# s! P4 S$ @
  814. /*                                                                                                                                                */
    " ?, C# B$ L. w; [$ T
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    / {, A! U1 G4 @/ a
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    ! C. F& U: T+ A0 Y( Y
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    2 D3 r' ^& n! [6 z5 c0 z  c) {
  818. /*          to exit AAI mode unless AAI is programming the last address or                */1 E  C, e/ |2 Z, S
  819. /*         last address of unprotected block, which automatically exits                 */
    ) F7 e2 j3 a; U; h- j# o5 a+ @
  820. /*         AAI mode.                                                                                                                        */
    2 k7 n5 [% _+ }' e  M
  821. /*                                                                                                                                                */, n# E9 F0 Z; m# P
  822. /* Input:                                                                                                                                */6 C% J, W9 w! e8 X" d5 H( h4 Y
  823. /*                                                                                                                                                */8 E5 H4 y5 `. \: y' ^- ^, X: e) Y
  824. /*                byte1:                1st byte to be programmed                                                        */6 ~, }' n4 f6 e2 M! e. u: |
  825. /*                byte2:                2nd byte to be programmed                                                        */" w8 |9 E3 w' I& G) w1 g
  826. /*                                                                                                                                      */: k) x2 _& I' `, E2 V" P) f. @
  827. /*                                                                                                                                                */! D, E$ F- J6 P/ f( ~) Q/ @' J
  828. /* Returns:                                                                                                                                */7 L  e- {) W' D/ z# }
  829. /*                Nothing                                                                                                                        */
    / N+ O4 N4 T: h) \8 b/ R
  830. /*                                                                                                                                                *// F9 w0 Z' v' `! V. {' E, w3 q
  831. /************************************************************************/
    ! D: V/ c: r. C* t% w- S
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)2 Q1 |, ?) e# m8 n! a/ L' l, C
  833. {: S5 Q1 K$ q" q" j: ^* X: h8 b, k7 N; ?
  834.         CE_Low();                                /* enable device *// |0 v$ T% t7 \$ H- \( W( `
  835.         Send_Byte(0xAD);                /* send AAI command */) w: y  C3 f1 ^  o" j
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    ! g9 t4 X2 Q- h% _% U2 I
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */* z& V  ^3 j9 s9 x
  838.         CE_High();                                /* disable device */2 H1 f0 e: P; K+ {9 M
  839. ( c- J$ A# q3 i. {2 r
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    . x2 m) T$ h: q+ }/ h, @3 R; W
  841. : U; d1 x) p2 i+ q
  842.         WRDI();                                 /* Exit AAI before executing DBSY */, n' O. _( _. ?( A( w
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */# W# [1 E# [/ ]" O2 g9 _
  844. }
    1 S% h8 V1 o, |- }! `: Q3 @
  845. 9 m$ c8 f, E5 K! D: X- J9 Q
  846. /************************************************************************/2 Y9 v5 k8 ~5 \* G+ V
  847. /* PROCEDURE: Chip_Erase                                                                                                */) _2 m: n- d) [+ x! w6 J
  848. /*                                                                                                                                                */% @/ o7 k9 s4 y& ~; C
  849. /* This procedure erases the entire Chip.                                                                */. X* m+ M. p* G9 N$ S% p
  850. /*                                                                                                                                                */6 r5 Q, g- i4 A" T4 A& |! [
  851. /* Input:                                                                                                                                */
      U2 T+ T$ n. s& X* @8 D
  852. /*                None                                                                                                                        *// m" w; X' Q6 v; m% Q1 _5 s0 Q! |
  853. /*                                                                                                                                                */1 A+ j% D6 Z1 V3 x$ Y, m% R' s
  854. /* Returns:                                                                                                                                */( t- g7 `8 o. c7 @" `: X! H
  855. /*                Nothing                                                                                                                        *// M* h. W/ q7 N8 `( J% F5 M
  856. /************************************************************************// f5 n: I+ G0 |4 j
  857. void Chip_Erase()7 l7 l2 ^2 K. f
  858. {                                                ( T( @- Z1 m- j& k
  859.         CE_Low();                                /* enable device */: ^. q- ?% N( w/ y; b: v0 `
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) *// q% p& x$ }, D2 P/ @0 R
  861.         CE_High();                                /* disable device */
    # u' F, Q' x/ z% }9 U5 q6 J
  862. }
    $ L2 E$ I+ K2 F) H
  863.   p+ b: H/ U0 Y' j' b4 N/ S- l
  864. /************************************************************************/
    + F! _( c+ i7 R6 O$ S
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    ) }. C/ A& Q4 j8 I, P9 w# t
  866. /*                                                                                                                                                */' F2 t% f0 z9 N' T# z8 h
  867. /* This procedure Sector Erases the Chip.                                                                */) P; r/ N1 S4 I+ T- {
  868. /*                                                                                                                                                */
    + h. W" j5 f/ J# B  z
  869. /* Input:                                                                                                                                */
    - ], f7 D6 K- \8 b( G& k6 T& a
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : N; l( V, `9 v# r& m6 m# ^
  871. /*                                                                                                                                                */
    $ B: o1 k. ?3 w4 l" L
  872. /* Returns:                                                                                                                                */
    8 v- f- N3 i* D' `7 \
  873. /*                Nothing                                                                                                                        */" N( `, E2 u/ Q! |
  874. /************************************************************************/
    ' s$ U5 V# {3 H" z
  875. void Sector_Erase(unsigned long Dst)" X9 t: H$ t. u( b! a0 m
  876. {3 E7 e/ \0 C/ o7 s) L# F. A
  877. 4 b$ ~5 ]& W: o4 i( E& |6 _; J( U

  878. , |" n  L$ Q+ @0 u6 ^5 `0 }
  879.         CE_Low();                                        /* enable device */# A; B4 J! Y. L7 ^& m- \
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    + L; V' Q+ u% t8 d( v/ ^% e
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */3 w( O% g4 g# ?, g( E
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));! U0 b$ e4 o3 Z" J$ r% D
  883.         Send_Byte(Dst & 0xFF);7 d# a7 g  }9 w& d
  884.         CE_High();                                        /* disable device */$ H0 R# V3 }$ S: a* G, r& e* L
  885. }        , t" N+ A8 a. }2 a6 y
  886. 7 W( D1 c( Q$ G7 m
  887. /************************************************************************/
    ' }1 k+ s3 g8 d) L1 Z
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */7 o; e+ D, y, d0 e; f8 j+ ]- y: w4 L
  889. /*                                                                                                                                                */) H( T6 \' Y) R* @) u
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    * r" `+ @4 K6 I" P
  891. /*                                                                                                                                                */: T3 [+ a+ Q; c5 G3 n
  892. /* Input:                                                                                                                                */( S- n+ f6 P2 f# Q8 \
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */, a' j' b% D) l, _+ Y$ [
  894. /*                                                                                                                                                */( i% @7 f/ v8 I2 p' Y
  895. /* Returns:                                                                                                                                */: O) [6 ]1 B1 ~
  896. /*                Nothing                                                                                                                        */
    ) Q  \& a: o' O1 x5 a* h* ~4 x
  897. /************************************************************************/9 c' _0 L& o* K; i+ b$ b" t9 M
  898. void Block_Erase_32K(unsigned long Dst)
    4 Q3 Z) ?8 u# \- k
  899. {
    ( i) a2 m1 X5 t( m8 Z' `
  900.         CE_Low();                                        /* enable device */
    5 J- K  H9 h3 I7 l
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */. `; d, C1 g# O  r2 q7 [) K; X
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    & k/ h$ Z7 G$ i' ~8 g( e6 R
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    & f2 ]3 t0 q3 i3 e$ l5 w
  904.         Send_Byte(Dst & 0xFF);
    ) m: P+ A; m+ e4 m! m
  905.         CE_High();                                        /* disable device */5 }8 h  P) ^' b  [/ N
  906. }
    5 |4 a0 S- v* H1 u9 T5 D; g

  907. 0 P2 s" D2 ~7 I, s! h
  908. /************************************************************************/
    ' N+ d, v- I" h$ t3 @1 P! ~
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */! y7 \+ S( {( t8 s* e* B% j- f
  910. /*                                                                                                                                                */" ~2 V3 b/ [" J  m; _8 E) k; P) |
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ! x0 f5 s+ `1 e. V  s, [
  912. /*                                                                                                                                                */
    # B! `' r8 V+ I9 }1 S% q3 Y
  913. /* Input:                                                                                                                                */
    / Z1 g( D/ a+ k$ k
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */0 p. B6 U" \5 S2 S8 C
  915. /*                                                                                                                                                */
    + }4 s! W/ l' G8 c
  916. /* Returns:                                                                                                                                */
    6 Q! Y* S, W( Q/ B* c7 }
  917. /*                Nothing                                                                                                                        */
    7 q9 N* j" b  [+ c4 W+ B9 g3 w
  918. /************************************************************************/0 g' R7 d" i9 I& \! z( o0 J
  919. void Block_Erase_64K(unsigned long Dst), [4 q# T; m# T0 t) T+ X+ O
  920. {
    & t; \( I/ m7 D- i2 M; @& |
  921.         CE_Low();                                        /* enable device */
    8 b9 S, I* M0 |& }7 e; b
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */" G$ R. n8 y. D/ B: d. d6 o
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ! o0 I9 c8 W3 k2 t6 g
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    $ b/ |  r" h0 t( m4 K! ]1 `
  925.         Send_Byte(Dst & 0xFF);4 H8 x7 I* N7 r" ~7 W  ^
  926.         CE_High();                                        /* disable device */
    " K1 j/ L( R8 A. \4 T' x) \
  927. }
    ( t: ^! f1 K3 T4 _7 v9 `
  928. 2 [9 G0 \3 K- y4 \
  929. /************************************************************************/
    " d1 l8 N' y/ C0 f9 I0 M
  930. /* PROCEDURE: Wait_Busy                                                                                                        */* e$ ~. L0 k/ g* i( Y
  931. /*                                                                                                                                                */
    $ e5 c. G+ L1 K" S
  932. /* This procedure waits until device is no longer busy (can be used by        */
    8 ^" H8 L" ^+ R1 d
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */2 \0 [" |4 }3 v$ l; z1 L$ {- [
  934. /*                                                                                                                                                */
    $ n5 G' E7 p! a
  935. /* Input:                                                                                                                                */
    4 O9 I. T2 x7 E" t3 m% S& l- a9 m
  936. /*                None                                                                                                                        */" ~; [) h$ W$ `/ N
  937. /*                                                                                                                                                */: v+ Q6 I: \" A+ u! ^1 w
  938. /* Returns:                                                                                                                                *// Q. Y3 P* \+ H: q) I& Q
  939. /*                Nothing                                                                                                                        */
    6 k; }' w- s% I( |
  940. /************************************************************************/& ]) H2 a+ x+ p, t3 p& A
  941. void Wait_Busy()
    : v7 v' M6 G) u. s% k! u. }4 v
  942. {3 \  Z: g% b7 u! |0 `8 A3 `6 D0 j
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    : [& W* O1 Z! N1 S/ Z; }
  944.                 Read_Status_Register();
    + o6 \5 K, v: O! X: o* F: W8 d( p6 ]( {
  945. }9 B$ _1 G5 {' X, A/ ~" `
  946. : s/ N! n& W9 U
  947. /************************************************************************/+ L/ N" t( Q8 I
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */: B5 U* t0 ?8 }) S0 H+ J3 ^- u3 x1 L
  949. /*                                                                                                                                                */
    9 Y% ]4 R( g% n! K" b2 A4 G
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    7 x4 M, k4 p0 ]( ~! z
  951. /*                                                                                                                                                */- T/ D. S# a$ R& T6 A' d' o0 ~$ j
  952. /* Input:                                                                                                                                */6 N  c  L: \* n) X1 h7 O- W1 U
  953. /*                None                                                                                                                        */' Z/ Y& `, i/ Z2 O9 g. ]( H/ q4 z& S
  954. /*                                                                                                                                                */
    * \, G0 W. d+ x  z: W
  955. /* Returns:                                                                                                                                */% W$ w/ K/ U; I9 J. R  [6 I
  956. /*                Nothing                                                                                                                        */' ]( `2 \7 C6 k9 V2 q& d$ q1 u& K
  957. /************************************************************************/
    8 G/ ?% t; t: `( c9 T" O, Q
  958. void Wait_Busy_AAI()6 f, ~+ t4 o; S1 R2 w* G. X
  959. {
    - R% I6 l0 z1 ~1 @/ S
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */9 s+ G4 H: ]7 ^( P8 g7 S$ c- J
  961.                 Read_Status_Register();4 _. v4 I* p0 ?+ r
  962. }0 X% l' y( l& a6 Z# [

  963. / N0 l' E" l3 a& q$ Y! f2 d
  964. /************************************************************************/
    5 N% n8 U8 H9 Y7 i, K  H
  965. /* PROCEDURE: WREN_Check                                                                                                */
    9 B7 E/ B! b% N/ ?6 {- I
  966. /*                                                                                                                                                */2 @; `; c3 h2 b2 d) K- k/ J
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    " }+ J8 C  ~- ]. M( e+ l" L2 a
  968. /*                                                                                                                                                */
    7 @, f% C! d* x. t
  969. /* Input:                                                                                                                                */
    + f# u2 W- u7 D, S) I
  970. /*                None                                                                                                                        */& F- y  d2 L3 m# Y) F
  971. /*                                                                                                                                                */: p, j& M/ ?: ]: b
  972. /* Returns:                                                                                                                                */
    5 u& G) Q4 V- |; b$ a2 X
  973. /*                Nothing                                                                                                                        */
    / a. y2 c! H" }' C9 ^' P# P: K
  974. /************************************************************************/7 ^* F$ y3 Q- K7 Z9 |& }
  975. void WREN_Check()
    ) i4 n3 ]0 D% N( D7 ~
  976. {. \* M. B8 D& \. Q% `% r
  977.         unsigned char byte;* r# K9 t5 s4 U. V) n; {
  978.         byte = Read_Status_Register();        /* read the status register */9 d( c( j% T( Y
  979.         if (byte != 0x02)                /* verify that WEL bit is set */8 k" d8 A7 O! D, ^5 Z% |0 B
  980.         {8 ^' Z7 _2 q) U, A( X1 d
  981.                 while(1)! s! v* I, u- f
  982.                         /* add source code or statements for this file */$ H- l$ O3 k& S
  983.                         /* to compile                                  */
    2 b8 r( B5 ~7 c( l" }6 y
  984.                         /* i.e. option: insert a display to view error on LED? */% f$ g% p5 H) [' w3 f
  985.                  
    9 _7 T. s" `* A- a/ Z+ c" Z! X$ P( O
  986.         }
    : {+ ]  L) ]( V6 A( o* ?
  987. }- I( J3 C& S* s: e) r$ i

  988. * @6 K  O. m6 p+ }
  989. /************************************************************************/( q9 Z6 `: M9 Q! U6 {
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */4 w# u# O! n; a" F/ Q; B# B6 I$ D
  991. /*                                                                                                                                                */
    * m) J; h  `4 u) y8 D2 J5 `: E
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    6 E4 e( d( y8 [) o9 H
  993. /*                                                                                                                                                */
    ; A- S# x( p( ~& T- \5 ^
  994. /* Input:                                                                                                                                */
    6 \' F& Z6 O' v) L7 S' Z. X- S
  995. /*                None                                                                                                                        */
    . R( d0 R# F7 Q" ^5 R+ g8 i
  996. /*                                                                                                                                                */
    : F; F& ?' r6 X- s3 D% J; G* {! G
  997. /* Returns:                                                                                                                                */
    ' ~: L4 H9 U( J6 W/ Y
  998. /*                Nothing                                                                                                                        */
    4 H. p+ }, {% s, l0 W* q  D. D
  999. /************************************************************************/
    9 a# j2 i+ F0 g" Q
  1000. void WREN_AAI_Check()' ?8 u+ d! t8 l% a9 N# ?5 I
  1001. {- Y; U2 ?7 x# p1 {) O) F
  1002.         unsigned char byte;3 k/ _. h# z: _
  1003.         byte = Read_Status_Register();        /* read the status register */
    8 o- a/ l! c' s% V1 _/ U' ^
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    2 @1 j7 T, ?  ]; d! R) H8 Y
  1005.         {
    - c/ ~* G! _- H( ?9 d! a
  1006.                 while(1)               
    ( `7 x) M9 r7 W9 H8 n8 A
  1007.                         /* add source code or statements for this file */2 p! e1 |+ E3 y; b6 l) i" f
  1008.                         /* to compile                                  */
    7 I' E6 _5 U3 r) {: i! S
  1009.                         /* i.e. option: insert a display to view error on LED? */! q" w! x0 @; f/ b3 q- A
  1010. 5 `* \, ?6 |  Z# l: G) s( G) }8 M
  1011.         }
    - q/ M# h8 ~0 U& j( f1 C
  1012. }
    9 a, `9 u& i1 o4 {* v0 [

  1013. $ c! m5 \6 c0 k: Z% a) N
  1014. /************************************************************************/9 C' w. p! c' Y  d: Q
  1015. /* PROCEDURE: Verify                                                                                                        */
    , X4 t+ h9 |3 @6 E* Y) |
  1016. /*                                                                                                                                                */
    ! C8 u3 g* @  Y9 c9 F5 @
  1017. /* This procedure checks to see if the correct byte has be read.                */: A1 V) w: e0 ^0 y- V
  1018. /*                                                                                                                                                */
    4 R; g* A6 F9 }6 G2 g1 [
  1019. /* Input:                                                                                                                                */
    8 v& T& F: T3 n, W* u- k
  1020. /*                byte:                byte read                                                                                        */4 ^. S) T3 q2 j
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    / O9 v& `- V* g8 B' O
  1022. /*                                                                                                                                                */
    ' i: \6 G0 R0 G$ P: N
  1023. /* Returns:                                                                                                                                */2 c& q' f5 c, q2 W) M- s6 |
  1024. /*                Nothing                                                                                                                        */
    2 m0 \: d4 d- a' @  E& @; j! }3 h
  1025. /************************************************************************/' Q; \  q' [0 e2 f( i" }* ~
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    : I/ z: B& K0 V; |1 h( f
  1027. {
    " g" K( A  l1 x7 T
  1028.         if (byte != cor_byte)
    2 K& D( P, P% o
  1029.         {# S6 r$ M) S1 L' ]5 g
  1030.                 while(1)( V; H5 ~) N' _6 A+ @
  1031.                         /* add source code or statement for this file */
      G" ]5 o. f, l8 N& G4 ?6 w. o
  1032.                         /* to compile                                  */! l& ?2 }1 U5 Y. f  H6 ?
  1033.                         /* i.e. option: insert a display to view error on LED? */; z- H; @7 v9 k! P$ x: P- }
  1034.                
    ! J& V+ D/ E+ Q& ?3 \8 {" R
  1035.         }1 w/ m$ S5 A/ g; h( J- F( Y
  1036. }
    & E( [3 {$ p6 V/ q, }) u" f
  1037. . T, p& ^& Y# R) ?1 _& c
  1038. 4 S- H; R0 U" ], {: i! j1 ^! U
  1039. int main()
    5 r$ i4 @2 a0 G, K, L( k
  1040. {
    . H9 \$ S: _3 Z  D0 D
  1041. 1 S! `, m1 L( Z4 l- t/ g
  1042. return 0;' U4 [% _" Z$ Y, ]
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
7 Z2 w' y" S# t8 b- {; `" \9 I   main()
, k0 E- i# \+ m) K3 x" \   里面怎么是空的呢?
7 P3 b! v' E6 C3 ^7 d   发一份给我吧
  j: K( w. ~0 k2 y7 D) zmail:luyijun2005@hotmail.com
2 P' y) V. f1 t# p咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。  c; A% v8 m4 j

2 F0 e4 c# X8 t3 e[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
6 f- i  b/ v, b2 O3 ZEC的代码在哪跑,你看DS的说明,每个EC都不同的。
) w: \2 W: \, u* ^4 f" F+ ]6 MOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
# F0 v# ]* E6 }9 t' s7 Y# }  M! X. ]上面几个问题是你没看任何东西而白问。* Q# N) Z7 w' ^8 E9 D

2 D8 S4 d3 w, P8 Q/ w至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。* S* s( S' i8 s5 c' Q0 n4 c
8 [8 _6 {# q9 Y' m% _6 k% ]
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!# ]+ y- L" `+ {2 S  u2 L; j
1 M+ F% k# Q& E! Y
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
6 [- }9 d* N% @2 L5 _# `5 x- a% u" }7 O$ R1 A6 |9 a" t
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...& A9 `) P8 t) G, f

: p* @% A9 V) H; U不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
* e$ k7 T& w$ y; ~3 Y/ ~似乎要把SPI能support 到最大,这EC chip应该有好卖点. [5 ^1 I8 o6 H$ P5 t, p
BIOS功能要不要强大,也就决定了SPI Flach的大小5 ]5 d6 h' |* p7 K3 j% {
我是这么想的~让OEM去决定要挂多大!! d% n: e: j5 l' D
如果我司有BIOS工程师就好了~哈8 K! Q9 f# D1 k2 k9 G8 z  j* J
WPCE775应该算很新的东西,来看它支持到多大?" }" L/ V; t1 I  v) A- K
; \% n$ @& M9 E1 @, C
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte; R+ \4 @7 ?: r
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
: W1 M" F) N: a& a1 E# T4 z! J& D
/ h: N# ~* u6 \5 |1 F) m这份driver收下~希望以后有用到
3 ^: N) j9 m- @, Z谢谢bini大大! E; Q+ N& m& X8 Z- S) Q
3 Z9 }* b- X/ v! ?; m4 Z
很新很新的新手,如有错误请指正 (准备看第二家的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()  M! g- x0 @) _: ^6 b# a
{
3 |& S! q9 c5 p        unsigned char temp = 0;
1 K; m4 G9 X8 V        CE_Low();
) P& K" e0 k0 Q# _: z    while (temp == 0x00)        /* waste time until not busy */0 h- B2 a6 W8 m; A
                temp = SO;
& [" |. F% K4 z* ~3 [        CE_High();
4 b- g) J: `/ i}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
# C! T1 A5 b( `0 ^7 s7 x0 F5 j{
0 A9 U1 L3 ~, H        
+ j% s( H' c0 ~. [        unsigned char i = 0;
- S; r1 ~* w' _# t0 _        for (i = 0; i < 8; i++)
+ @6 U6 E+ P( J$ S        {% ]- k. |" a2 w4 x4 o6 _
               
. I, v3 ~5 n( r                if ((out & 0x80) == 0x80)        /* check if MSB is high */
5 I! T5 L* Y+ t8 n3 n                        SI = 1;2 m) |  c2 H! T( L0 P& A
                else
9 g9 {5 G: M7 N3 k. X2 U( e+ \                        SI = 0;                                /* if not, set to low */
" E. e3 K" T3 Z, B& C0 N3 r5 ]5 c 问              SCK = 1;                                /* toggle clock high */
. \" ?: U" I0 o- o. t   题            out = (out << 1);                /* shift 1 place for next bit */6 _; u6 Z+ z, {& M1 q1 w
                SCK = 0;                                /* toggle clock low *// i* y. Z4 x% s3 E
        }
4 q: s' e$ i2 f/ M}
0 Y! g3 Q$ D: y3 A! W 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-9-4 14:44 , Processed in 0.077820 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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