找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55639|回复: 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) ~% Z  P8 n% [/ ~/ q

  2. - _# p) |) ~' ?+ N, b( m9 X3 V- c  O
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    / H5 y2 [1 ^5 g( Y- C
  4. . C% v0 q! f3 Z( K- V
  5. November 4th, 2005, Rev. 1.0
    # o& i! N) u  z
  6. % c, d5 G' f3 P, t
  7. ABOUT THE SOFTWARE+ G% S& c# R3 ^: U$ z3 Y1 o2 g
  8. This application note provides software driver examples for SST25VF080B,
    # ]8 i9 P! f3 p9 r8 F
  9. Serial Flash. Extensive comments are included in each routine to describe
      V" i6 T0 U; {& W
  10. the function of each routine.  The interface coding uses polling method : U- P  X0 i- F3 t$ l2 j
  11. rather than the SPI protocol to interface with these serial devices.  The7 X7 ?. ?  j" x5 I# t9 Z. u' a
  12. functions are differentiated below in terms of the communication protocols9 E+ H" {% ?+ F7 Y) Y( T/ d
  13. (uses Mode 0) and specific device operation instructions. This code has been
    4 {4 t4 ]( s0 {8 q! k" Z; ?' S  R
  14. designed to compile using the Keil compiler., P: F& Z+ c& O8 Z
  15. ( \, j6 F7 O) [% Q* A6 q9 ?
  16. 7 k9 W3 x, R. _* c' i+ I& a7 K
  17. ABOUT THE SST25VF080B' u0 f6 P2 U7 h8 Q
  18. 8 Y: w& T2 U3 v$ \" I1 U$ [
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    & J0 t& E5 l; k% |& C8 S* Y
  20. conjunction with this application note for a complete understanding
    : `" G9 V0 u2 o# a
  21. of the device.! W7 Y. t9 Y( o- E. B4 m4 Y6 T3 v
  22. & h( W( h6 m( t

  23. / h* y0 \  R& _4 l; _
  24. Device Communication Protocol(pinout related) functions:
    7 P2 B. ]- y0 D( A
  25. # j3 M# W, L, Q3 R
  26. Functions                                    Function' E* F) o* }% }* j
  27. ------------------------------------------------------------------( p9 |. b& I3 y5 _9 M8 H
  28. init                                        Initializes clock to set up mode 0.  v/ j- @* u2 h  E5 X+ N
  29. Send_Byte                                Sends one byte using SI pin to send and
    # p9 b6 S: `7 l# D/ Y! n
  30.                                                 shift out 1-bit per clock rising edge: {1 \& A! ?+ w& h2 s* E
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    5 p) Q# D' S  G4 k
  32.                                                 in 1-bit per clock falling edge
    ) ~- e/ i$ S8 Z' q" _  o( w7 i! e8 ]3 A8 t
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    / w% Q6 |$ k* a9 z7 V. a. S( T
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    4 A& Q: F" V0 {8 J# v
  35. CE_Low                                        Clears Chip Enable of the serial flash to low% {: D5 ]$ O) G% _$ k% \; J
  36. Hold_Low                                Clears Hold pin to make serial flash hold! C/ d$ G, z% u, A( y
  37. Unhold                                        Unholds the serial flash
    5 f5 L3 q% k1 |2 Z* {* A: X
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    " r( i2 |6 x* z: s3 I! D
  39. UnWP                                        Disables write protection pin3 R* H% B7 T$ W$ M  {
  40. / D  i( J, ?1 W
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
      ?  h# {5 O3 L+ Z4 j, u
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your, H( |1 P& i' ?* R8 n6 e
  43. software which should reflect your hardware interfaced.          ) A3 ~. {2 V! O% r) t7 w! G$ m" h

  44. 3 x! o# A1 M) S

  45. - s! _8 \% l, H, y7 r) [" a( R3 i
  46. Device Operation Instruction functions:
    3 D- x* z% c4 d  L5 g8 o
  47. * O8 E$ B1 O0 Z
  48. Functions                                    Function, m( s3 A9 q" G, T
  49. ------------------------------------------------------------------
    6 T) @1 r, H0 p3 F' P& A
  50. Read_Status_Register        Reads the status register of the serial flash
    - F! j/ u+ k# K) \7 g
  51. EWSR                                        Enables the Write Status Register
    6 ]! {2 c" ^. Y. A8 M6 o8 w6 b
  52. WRSR                                        Performs a write to the status register
    & [* T9 A; U6 H  Y: ?" \# M
  53. WREN                                        Write enables the serial flash9 x9 V% p1 U& E7 s/ U! M
  54. WRDI                                        Write disables the serial flash
    ( F8 Y& |& N- p" [
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    7 g1 Y+ R3 V7 S  p2 S% r
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming  _' @/ V( u: t/ O9 v1 J+ ]# D
  57. Read_ID                                        Reads the manufacturer ID and device ID
    ! `4 f6 a+ @( Z; w
  58. Jedec_ID_Read                        Reads the Jedec ID- b9 K' Q6 _: A  [
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    3 y! B9 F& A5 L9 Y) Z
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)" I, t: o* B" O7 _  i
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)6 p/ s# L8 E3 Z
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)) e2 n2 t( g) @4 U
  63. Byte_Program                        Program one byte to the serial flash
    ; }* j! k8 c& u+ V6 K* A# R: k
  64. Auto_Add_IncA                        Initial Auto Address Increment process7 E* H/ N; L$ V4 ^
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation) P/ J0 R: K/ Q- D9 j; ]
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY3 Y9 Q" j- C) I, F: {
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY7 W9 r* e. X3 t
  68. Chip_Erase                                Erases entire serial flash
    # _: M" A: K7 ~6 s
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    ( ^5 u# I' N& S
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash! r7 i) l9 T9 F3 f6 {" R" U
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash) }* X% h. K" a+ z; M1 }
  72. Wait_Busy                                Polls status register until busy bit is low
    * i& t0 z# l4 q  k& R
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming; [  P) t- G: h/ ^% E! ~0 P7 h
  74. WREN_Check                                Checks to see if WEL is set
    " |. Z4 k9 Q( Z0 {1 F# g: [' d4 C
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set7 o0 Q3 J, }6 @. X' \

  76. . d6 v2 t6 i8 v6 r+ N- J
  77. 6 l( G  W% \( c  ?
  78. % E6 r& P7 n* A- k6 i& q
  79.                                                                      
    * h, p  ~, E- G
  80. "C" LANGUAGE DRIVERS
    , K5 e) h. j# R* c

  81. 0 [. K0 I3 i' G$ J
  82. /********************************************************************/7 F2 G; `" i% n7 q% v
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    " S/ ?8 X3 D- I4 Z. D
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    : x* f0 ~& v. ~6 [! \* A# D
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */! ?" F7 J. `, v9 k  m  d9 K2 }/ W
  86. /*                                                                  */, Y7 O9 r$ P: U
  87. /* Revision 1.0, November 4th, 2005                                                                          */   + c+ Q5 L; j* M. Y6 j2 [+ W" `
  88. /*                                                                  */
    8 T/ ~! T/ q4 y+ S
  89. /*                                                                                                                                        */: E0 A: |8 T, o# y
  90. /********************************************************************/$ R$ a% F% R: `1 [& T

  91. , _" Y7 ]9 y; t7 K$ _' Z
  92. #include <stdio.h>
    & u' O9 X1 G3 z7 B' z* w
  93. #include <stdlib.h>
    ! _3 j; Z3 f; T1 c( f
  94. 4 z* @3 B1 \" M
  95. /* Function Prototypes */3 T2 p0 n& ^9 i+ m5 s
  96. % C- y. g+ U$ j) N2 V
  97. void init();) `$ K; O* P) [. Z3 Q+ [" y
  98. void Send_Byte(unsigned char out);; _  g% B5 k/ x7 [
  99. unsigned char Get_Byte();
    : Z$ \& z* s) a3 Z, y
  100. void Poll_SO();* ]; l, L6 s$ c
  101. void CE_High();  y4 G) v1 w; [! U- x- z
  102. void CE_Low();
      W2 i6 u, j8 v( C. `, x
  103. void Hold_Low();
    & q3 Q! }! _+ u0 H% K# _2 E
  104. void Unhold();% n2 U9 [) A2 Z5 f+ v
  105. void WP_Low();
    " E9 `6 e, U0 Y9 R2 b
  106. void UnWP();) i( [) V7 d$ \) y3 [
  107. unsigned char Read_Status_Register();7 M/ W( k; i  R
  108. void EWSR();9 S$ O- X; @: S  k, S  a5 d! P
  109. void WRSR(byte);/ Z, x/ R- x$ ]9 _
  110. void WREN();
    7 V+ @& A9 D$ e+ f7 a2 ]
  111. void WRDI();' K' @8 ^: p( b
  112. void EBSY();1 j! l3 x+ e9 l; u) @1 i, g3 j
  113. void DBSY();
    2 G$ m9 E& E) K' u. I5 i
  114. unsigned char Read_ID(ID_addr);
    * N" C% C/ F$ M3 Y: B- S
  115. unsigned long Jedec_ID_Read();
    - k% c3 F3 X/ _
  116. unsigned char Read(unsigned long Dst);
    8 M9 P7 H* @+ X( Z1 ^
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    . Q9 c5 ]# }- J  s0 _
  118. unsigned char HighSpeed_Read(unsigned long Dst); ) a( `1 o* Y  |, w7 N
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    8 i7 W# r. x! c
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    ! Y- W! @$ K; o
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    # H$ e$ V% n- Q
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);+ f: n* i: Y* |! _" g1 z
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);  }3 U) K  o$ ^$ _( \5 O4 t
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);8 ^) R) C4 N3 I8 ^+ A
  125. void Chip_Erase();9 Y' d, I9 R! R( e' w
  126. void Sector_Erase(unsigned long Dst);8 T, W" ^7 Q6 Q( B/ ^0 Y
  127. void Block_Erase_32K(unsigned long Dst);8 T# ^- I) Y% W6 ?$ m
  128. void Block_Erase_64K(unsigned long Dst);
    / }5 p5 [6 J3 Q- W7 `
  129. void Wait_Busy();
      N; b% |- M  j
  130. void Wait_Busy_AAI();1 u4 O4 s! p% N2 H. j8 E' H" ^
  131. void WREN_Check();/ R8 s  u# z, w' w$ P6 [6 n1 h
  132. void WREN_AAI_Check();. v3 L" {0 `0 y- @- @: J

  133. + B) Y* Z+ d0 _! J6 H9 d- x
  134. void Verify(unsigned char byte, unsigned char cor_byte);* k; C4 i% K% X2 i6 W  V3 E
  135. , [4 ~3 D, E* h, Z" W1 M
  136. unsigned char idata upper_128[128];                /* global array to store read data */2 [, X* ^; s; f" J, d
  137.                                                                                 /* to upper RAM area from 80H - FFH */% ^3 t+ s  s& S+ `' i

  138. 7 k% ~) w$ v0 r4 O* A
  139. /************************************************************************/+ M/ A1 S  U) e$ m& }2 r1 j/ U
  140. /* PROCEDURE: init                                                                                                                */7 {9 n. A% s# I( J/ w
  141. /*                                                                                                                                                */6 z; j8 @# `3 c- g' W  Y# T+ d
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    , r; }; N8 k9 m
  143. /* setting up mode 0.                                                                                                        */
    ' m5 L  K  B2 [! e% Q4 d+ s# s% D# p
  144. /*                                                                                                                                                */
    ' J+ f3 U0 Z, p8 x
  145. /* Input:                                                                                                                                */  L# v$ M* B8 k  g% v7 W
  146. /*                None                                                                                                                        */
    # r; n& n0 h" h6 o1 r
  147. /*                                                                                                                                                */
    # `2 P1 D. O5 @) m# `7 N
  148. /* Output:                                                                                                                                */
    * V2 o$ Z9 s2 P: p& d5 \$ ]
  149. /*                SCK                                                                                                                                */* x% |4 E, N9 V" R/ K) R
  150. /************************************************************************/) f* g/ x; V; A/ W  x0 n$ U
  151. void init()7 m- ]* u1 P: M8 n/ S4 q
  152. {
    2 y5 V! s: g5 Z* ^
  153.         SCK = 0;        /* set clock to low initial state */
    1 w( W1 b  S$ C3 Q' _8 Z5 s2 H6 k
  154. }
    " ]: K! n7 U- i; u  ^  b8 u9 O# u, \. r

  155. - R# q- x  Y; r6 p5 \; Z2 y
  156. /************************************************************************/
    " s. |+ t: w/ d, r0 J' g
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    - X4 p( b  S9 I
  158. /*                                                                                                                                                */
    6 N6 r! U9 y. C/ M) k
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */+ c( `) r' G4 G0 Z, p
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    0 _, J% ^) ]+ v( F
  161. /*                                                                                                                                                */
    $ h: ^/ q# k1 |% V( V7 L
  162. /* Input:                                                                                                                                */
    ' U! U  ?+ r& @! L
  163. /*                out                                                                                                                                */9 s0 h* b) j/ p$ o3 z. z
  164. /*                                                                                                                                                */
    & k8 G2 f. @/ u% H8 {
  165. /* Output:                                                                                                                                */
      m9 |/ A9 m+ A% L- y
  166. /*                SI                                                                                                                                */& j/ U8 ?$ \0 H, _0 ~8 r
  167. /************************************************************************/
    ' ]2 h6 d! D! T, z# E
  168. void Send_Byte(unsigned char out); r$ y1 U" m) F! ~
  169. {
    * r9 T  V! {6 u6 Z# Y" p- M9 S
  170.        
    + H. `: x, _& Y6 k
  171.         unsigned char i = 0;
    2 X+ |4 [! v' [: w  j
  172.         for (i = 0; i < 8; i++)0 l8 K  w: t& i( J
  173.         {* V9 g* G0 a7 j! [. ]0 n3 M
  174.                
    # L* {& w% ?4 D9 w8 U8 u0 o% ?" r
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    9 c) o. U+ R# U
  176.                         SI = 1;' w7 C, W) c' V1 U* B: \
  177.                 else) p! _3 |) i' ]+ V
  178.                         SI = 0;                                /* if not, set to low */+ O. X4 ^+ I2 @, v" K
  179.                 SCK = 1;                                /* toggle clock high */" }. f1 @2 a9 X! \% E2 S$ `
  180.                 out = (out << 1);                /* shift 1 place for next bit */0 I( }$ k8 A. p+ e' o8 O& C
  181.                 SCK = 0;                                /* toggle clock low */
    , h4 m& t5 \2 u6 @
  182.         }, P# r) M8 y" Z
  183. }4 p* F7 w. M( }( a6 v
  184. 7 b0 |! M9 z* D7 B
  185. /************************************************************************/
    ! M/ x" Q; T0 K2 c
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    6 \5 P8 k8 k# V  ]" l3 G1 K# ~
  187. /*                                                                                                                                                */
    . J* a. Q! C" N- {) J( z
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */- G% H8 L4 f+ i  |2 T/ |% O: f
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    1 `0 a, x$ ?: W% x3 A8 |, W
  190. /*                                                                                                                                                */) }+ n: L( f6 X5 S
  191. /* Input:                                                                                                                                */" T0 X5 O/ ^- `. Y) ?3 P2 q& z( V
  192. /*                SO                                                                                                                                */
    ; s2 l" f: r. _0 t+ i% G
  193. /*                                                                                                                                                */- ?  P& N. O( z( I
  194. /* Output:                                                                                                                                */
    1 j5 t3 Z- E6 L/ e( k  }6 a& v
  195. /*                None                                                                                                                        */
    + o2 Y. R" k, ?; N7 ]& v) a6 A" D; W) v5 e
  196. /************************************************************************/3 d' }( [* ^# W) f$ w" K" l
  197. unsigned char Get_Byte()) E% h: h* h3 [; I% M. R/ W
  198. {/ s7 D& i$ B3 G6 m7 v8 y
  199.         unsigned char i = 0, in = 0, temp = 0;! l6 `& J% e4 U) b
  200.         for (i = 0; i < 8; i++)
    * G. h0 E5 d5 Z6 N) S9 R$ A
  201.         {0 i4 j) F/ z: f$ w1 e# z1 n
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    " C% E* ]6 k, a) I2 F! ~
  203.                 temp = SO;                        /* save input */; @5 R0 M7 x; e/ m
  204.                 SCK = 1;                        /* toggle clock high */
    3 x. c1 Z' J4 F3 n+ o' g
  205.                 if (temp == 1)                        /* check to see if bit is high */1 }: D6 X: E) P. j5 u) c6 M
  206.                         in = in | 0x01;                /* if high, make bit high */1 V) t, P# G3 B

  207. + N3 g2 [2 b3 N4 Y. _& ~
  208.                 SCK = 0;                        /* toggle clock low */9 k% X8 N* y7 u$ q2 M

  209. % z3 o8 r+ L9 |& r: H$ ^
  210.         }
    & Q! X+ J! o# w. |* f, H, d9 {6 s2 p
  211.         return in;
    4 B* I5 c4 s  @9 S2 P' A) f
  212. }
    ' e  `: i% K* c+ Z

  213. & w, m! P2 Q8 \5 |! [
  214. /************************************************************************/- y  E8 o) i- Z# I/ |
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    ( ?0 R7 ^( R& p* }2 ]3 g
  216. /*                                                                                                                                                */% l8 S, l, u, q) c9 Y1 R4 R: s
  217. /* This procedure polls for the SO line during AAI programming                  */" I. }' y  d* k, n
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    9 @1 [7 h; P/ e: n0 p; r: ~
  219. /* is completed                                                                                                                        */
    & Z. s; P& x2 L9 g: _$ Y  b/ Q# M
  220. /*                                                                                                                                                */
    / g$ h$ s1 ?% a, f6 v
  221. /* Input:                                                                                                                                */1 W/ H2 y+ o) k7 v& i
  222. /*                SO                                                                                                                                */
    # `) d) i1 s+ F( t1 s+ r
  223. /*                                                                                                                                                */
    ! F4 k( D3 ^8 g2 G$ X3 S8 \
  224. /* Output:                                                                                                                                */1 n/ s* ^+ E: W! E' q1 \. n
  225. /*                None                                                                                                                        */
    + N( x* ~# k$ h0 G
  226. /************************************************************************/
    2 [- k# q. g: }* b9 y4 {: h
  227. void Poll_SO()
    3 _1 B8 D) K& s
  228. {1 }% f  U5 B5 j7 Y- t* \
  229.         unsigned char temp = 0;8 J( w6 T; k2 O; X1 }
  230.         CE_Low();; x8 z+ ^3 z% D8 e# E3 t7 h
  231.     while (temp == 0x00)        /* waste time until not busy */
    " Y  d$ k0 S. V" i
  232.                 temp = SO;
    9 l+ p, g' t1 b- g8 h$ v  o
  233.         CE_High();4 b* l# r1 f7 B& Z% O, V, M
  234. }
    ; k4 L8 K, a. D
  235. - x! i# X8 n7 ^: m- b$ d! z6 s) H
  236. /************************************************************************/
    7 r* T9 J8 y: S, O/ D( v
  237. /* PROCEDURE: CE_High                                                                                                        */
    2 c* _! P' @$ ^0 f
  238. /*                                                                                                                                                */' V2 K* N9 n* W9 [! P
  239. /* This procedure set CE = High.                                                                                */
    ( I+ ~; ?, E7 z4 h# W
  240. /*                                                                                                                                                */
    & e8 w$ x: P4 Y& N
  241. /* Input:                                                                                                                                */
    ; f3 [& E: ~% |2 n8 d2 S0 t& N
  242. /*                None                                                                                                                        */9 O9 K, L" M' E
  243. /*                                                                                                                                                */# F7 d9 L7 ~2 p/ p) Y5 @
  244. /* Output:                                                                                                                                */
    ! I# U6 Z/ N+ W
  245. /*                CE                                                                                                                                */
    $ }7 z0 A! ?' ]) S* r
  246. /*                                                                                                                                                */
    1 d* ?$ m7 u5 O& U( b# T
  247. /************************************************************************/
    8 t- Z6 X; e1 L1 `& }: w
  248. void CE_High() : D1 l* b, j, g# h
  249. {
    ( l: t: Q0 u5 H1 x3 b
  250.         CE = 1;                                /* set CE high */
    * k! K* ?4 _& V5 F* D
  251. }
    + P) C, Y) {1 D6 y

  252. . }  }2 {7 y! ^
  253. /************************************************************************/
    4 U+ r$ S9 \7 }+ Z- d
  254. /* PROCEDURE: CE_Low                                                                                                        */
    7 |( {$ ?  r. g$ F  r( c4 o
  255. /*                                                                                                                                                */+ V: O$ ]) J. L, H2 X
  256. /* This procedure drives the CE of the device to low.                                          */% Z; G! R: R. R( d4 g7 S
  257. /*                                                                                                                                                */; s. f5 A, Y+ G' B$ u2 {9 N
  258. /* Input:                                                                                                                                */( \( Y. G* H$ i8 u" ~) h7 ]
  259. /*                None                                                                                                                        */
    . x3 N8 n+ T9 i3 D
  260. /*                                                                                                                                                */
    - Y" v$ K* L+ O+ w
  261. /* Output:                                                                                                                                */" Z7 |5 M9 [, M
  262. /*                CE                                                                                                                                */
    ( h* _( X: u, h
  263. /*                                                                                                                                                */7 `$ G8 y8 C3 [$ ]4 B8 E+ h
  264. /************************************************************************/
    9 R. `) t4 m; J5 V! E0 Q
  265. void CE_Low()
    4 w" t3 n) |  {7 b4 k
  266. {       
    , v6 V- H. Q* N
  267.         CE = 0;                                /* clear CE low */) ~. \4 Z. ~3 j5 @0 U7 ^4 \, {0 J
  268. }
    ; o5 \1 y; z+ d& f! \

  269. ( Y/ E% t& K  W: t- n, Z( x
  270. /************************************************************************/! g! m6 u! `7 ]% [+ o4 `
  271. /* PROCEDURE: Hold()                                                                                                        */) q# j3 M9 N9 E
  272. /*                                                                                                                                                */
    5 x5 w' l+ L. F7 B& {$ R  P
  273. /* This procedure clears the Hold pin to low.                                                        */
    7 [: m2 l, T8 r3 N& Q6 r
  274. /*                                                                                                                                                */
    8 y  w& Z) _5 c2 t5 l* [
  275. /* Input:                                                                                                                                */- Q2 O  S  A7 M/ w0 k
  276. /*                None                                                                                                                        */
    / y" \! D  D) P5 H$ n; q/ l5 {
  277. /*                                                                                                                                                */- f& h  r, A8 C# @
  278. /* Output:                                                                                                                                */3 Y' s- r( N) r, L: O( z
  279. /*                Hold                                                                                                                        */
    ( o, l: x2 }) j2 ^9 [  O) }7 }9 X
  280. /************************************************************************/# }0 g. z+ E( b1 O% _$ l! B3 Y; A
  281. void Hold_Low()8 Q+ o1 A! }% N2 ], O7 Q$ H
  282. {# p9 B2 L. `) Z/ ?  I
  283.         Hold = 0;                        /* clear Hold pin */" s% M6 D4 A3 q; b* E$ ]
  284. }4 G' X* J  H# L7 X0 v3 h9 `! f/ Q

  285. + d3 u7 `7 n( ^! ?: M; H, d
  286. /************************************************************************/0 \2 L9 f5 r# K% c, l4 h
  287. /* PROCEDURE: Unhold()                                                                                                        */5 k' X* N7 e( m; T( j/ P) F" b5 P3 i
  288. /*                                                                                                                                                */
    : r" M0 t$ h" V, n; I
  289. /* This procedure sets the Hold pin to high.                                                        */
    - b! f. T: }" x6 Y
  290. /*                                                                                                                                                */
    8 `" E9 n- m" y
  291. /* Input:                                                                                                                                */3 l$ J! h2 f1 [% ~
  292. /*                None                                                                                                                        */" T- z; }4 j( O& ^, s2 g
  293. /*                                                                                                                                                */% J) E6 g' D' m7 {' {
  294. /* Output:                                                                                                                                */
    8 p  N, d' ]! {1 ^
  295. /*                Hold                                                                                                                        */1 R' c3 o9 T, y
  296. /************************************************************************/
    : ?, m5 J5 ?5 p! j/ B0 I
  297. void Unhold()5 h' O( r/ Z( t& H9 P% b
  298. {8 B0 a( U  n, g, ]$ l( R
  299.         Hold = 1;                        /* set Hold pin */  l; Z6 K' o2 L0 T* t
  300. }
    " ~# L+ L! Z9 `$ P4 F% @# W# F  k
  301. 5 u0 L' ?! Y/ j/ I5 L7 R; S# J
  302. /************************************************************************/& l$ W2 \2 h5 {' S8 O
  303. /* PROCEDURE: WP()                                                                                                                */  A/ E2 o4 J2 X/ h9 @
  304. /*                                                                                                                                                */
    4 L0 f) x4 {3 }4 }" I; q
  305. /* This procedure clears the WP pin to low.                                                                */9 i$ _* f; \' V7 T5 B
  306. /*                                                                                                                                                */
    - }9 G( h. ^; D5 V
  307. /* Input:                                                                                                                                */9 d; F' [# \- i" A  a; n
  308. /*                None                                                                                                                        */* r4 K% k. c( Z5 J4 v3 N* `& B
  309. /*                                                                                                                                                */8 v4 g1 O- i1 {5 [, o) H
  310. /* Output:                                                                                                                                */9 p, L/ t7 t5 x, r( _* R
  311. /*                WP                                                                                                                                */
    + V' ?6 p0 f3 g& q+ ?
  312. /************************************************************************/
    % A7 ^$ u( ]) `7 Q7 u  @
  313. void WP_Low()
    9 p% G- I! \2 \1 R6 b- [/ {
  314. {
    % {! n/ v) M4 ]  ~$ F. L6 \
  315.         WP = 0;                                /* clear WP pin */' C( e( T% |0 p' x$ @9 E" H
  316. }
    / [7 X) R& `, _- Y2 u+ `) h
  317. 8 t- ], o2 {: v, V
  318. /************************************************************************/
    7 _' R& a, Z& H- l2 Q
  319. /* PROCEDURE: UnWP()                                                                                                        */
    " b" e( W; ^3 |5 X+ B. @
  320. /*                                                                                                                                                */$ w( z( y' v& V9 ]5 X) h5 h
  321. /* This procedure sets the WP pin to high.                                                                */
    $ {; H+ Q% j/ F$ |& w( E0 I4 C
  322. /*                                                                                                                                                */# P( n6 R' o* p% `6 q$ g9 h
  323. /* Input:                                                                                                                                */# }9 o: q) a' k: u: `
  324. /*                None                                                                                                                        */
    9 J- K. T$ J' t- e& ?  t. ^! z
  325. /*                                                                                                                                                */
    5 f8 v2 c- S/ Y' B
  326. /* Output:                                                                                                                                */' v% Z) b( t7 A( Q
  327. /*                WP                                                                                                                                */1 G' ^2 ?% s0 z  U+ t' d3 W
  328. /************************************************************************/+ o0 V5 u- o. K" D! b3 q
  329. void UnWP()
    * V; `; Z; ?& d' c9 d1 m; a4 y
  330. {
    4 G" r1 I7 D7 X' d: x& W
  331.         WP = 1;                                /* set WP pin */$ f3 O, h* D9 I, o( k4 [
  332. }
    0 n1 G! `" f$ R  v

  333. $ A, Q" ^& k# @: `
  334. /************************************************************************/
    ) ]' h/ g& T1 v4 t
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    + }2 m# x/ R6 U* K& w, P
  336. /*                                                                                                                                                */
    / I7 |+ l0 C) g" \  `2 o% s
  337. /* This procedure read the status register and returns the byte.                */
    " G/ d7 S, d/ Z
  338. /*                                                                                                                                                */
    ' c8 z* v' L, d# j( c6 }) C7 a
  339. /* Input:                                                                                                                                */8 y" @- j/ M, m: u6 ]7 F. g* l
  340. /*                None                                                                                                                        */
    + r5 H* Q) ~$ X7 }6 k8 ~7 L
  341. /*                                                                                                                                                */7 Q# K: W1 s2 {- y8 Q/ a
  342. /* Returns:                                                                                                                                */
    " R5 y* [' k2 I& _) ]! t/ ?
  343. /*                byte                                                                                                                        */
    # @; k/ `- o% n! v! |8 z0 b
  344. /************************************************************************/* |5 I2 _; s$ L3 p( S
  345. unsigned char Read_Status_Register()) \+ ~# g- c% v5 q" [
  346. {
    . ?% @& G2 E& y% B; C3 ]
  347.         unsigned char byte = 0;" w) `7 _; F* Q2 m. Y9 U
  348.         CE_Low();                                /* enable device */& j5 a. B9 o. Y- M7 m
  349.         Send_Byte(0x05);                /* send RDSR command */: M7 U: A# m6 f' q
  350.         byte = Get_Byte();                /* receive byte */
    $ z4 l5 H$ W1 k. \( b
  351.         CE_High();                                /* disable device */
    8 l) ^% _9 Q) L5 @# q
  352.         return byte;; S3 M2 i3 r) Y# j5 W6 `
  353. }& o# ~0 N0 ^+ g+ t  c

  354. & X- n  s9 A9 \) [3 e
  355. /************************************************************************/
    0 }3 V9 B5 M+ R  y6 l. o; y
  356. /* PROCEDURE: EWSR                                                                                                                */
    2 ~5 t; k* {1 _5 z: t
  357. /*                                                                                                                                                */( I/ T, {8 U5 l# c/ K
  358. /* This procedure Enables Write Status Register.                                                  */, K' \- ]2 e$ G! @" R
  359. /*                                                                                                                                                */
    4 w+ _3 B5 t: g9 A( l3 [
  360. /* Input:                                                                                                                                */
    # y; c6 J9 U2 d1 F
  361. /*                None                                                                                                                        */5 I5 U9 e2 ]  l8 {  k8 ~
  362. /*                                                                                                                                                */
    ' B9 Z' L6 n  Z+ @* d
  363. /* Returns:                                                                                                                                */0 G$ }& B; u" Q1 q9 T
  364. /*                Nothing                                                                                                                        */2 z  K5 J: P( F3 ^) I3 p) F- l& b; q
  365. /************************************************************************/4 M1 m  G% D7 d4 J6 ^- J! `$ G& {
  366. void EWSR()
    ) U( D; F  e3 U: D: c0 _
  367. {0 K% n. `4 y$ |# O0 B% n
  368.         CE_Low();                                /* enable device */' J7 U( H5 l6 [3 M
  369.         Send_Byte(0x50);                /* enable writing to the status register */( e9 a; v& w2 y2 r  Z
  370.         CE_High();                                /* disable device *// c( G7 K) f- n
  371. }
    9 n# W7 o2 w0 R# Z
  372. 6 R% e2 O. z+ m# I3 C
  373. /************************************************************************/1 U3 B& h) ?* k
  374. /* PROCEDURE: WRSR                                                                                                                */
    " C7 T$ S0 u* y) m0 u
  375. /*                                                                                                                                                */
    4 n: c5 N: z# _2 `7 l7 Y
  376. /* This procedure writes a byte to the Status Register.                                        */* e) E7 Z# A; H1 w: p
  377. /*                                                                                                                                                */
    / l; U, T/ v& X
  378. /* Input:                                                                                                                                */
    ! {2 Q' ?+ X; i
  379. /*                byte                                                                                                                        */
    9 E8 N7 q' S. W1 W
  380. /*                                                                                                                                                */
    8 O1 O, z1 Q7 D  o8 G
  381. /* Returns:                                                                                                                                */
    ' ?3 a& s7 R' o
  382. /*                Nothing                                                                                                                        */* c6 ?1 V4 L2 p/ T$ |
  383. /************************************************************************/
    & A0 t# m1 l* l
  384. void WRSR(byte)
    7 ~! N$ V) ]; Z+ n, G
  385. {5 p* Z, D) b* L. S0 E
  386.         CE_Low();                                /* enable device */. _1 q6 a! G1 W: s2 \
  387.         Send_Byte(0x01);                /* select write to status register */: ^. e6 {# q- H: g
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    2 B5 X4 q7 g$ `" u
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */! @" S0 X; A0 b7 v, S
  390.         CE_High();                                /* disable the device */2 z- U( K# m  b# Y( V
  391. }
    4 R" J' A( V) g) q( B* q; Q: T
  392. 4 ^5 t6 h$ P; Y- S. Q! ]  K" K
  393. /************************************************************************/
    ; }+ w7 N4 W  c- N1 q: ?4 j2 t
  394. /* PROCEDURE: WREN                                                                                                                */
    / z; g; g" ?2 @4 p& g$ O
  395. /*                                                                                                                                                */* G7 ?: [2 J$ i) x
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */) B. B- N( S5 y# x) v6 G
  397. /* to Enables Write Status Register.                                                                        */0 W  ~! F4 D7 @8 B9 ~% j& a( k0 Y6 ?$ C
  398. /*                                                                                                                                                */
    9 ]1 ]3 [0 ]9 F# \8 p
  399. /* Input:                                                                                                                                */
    3 s  V8 _; f/ S" V  N2 A
  400. /*                None                                                                                                                        */
    1 d2 v- s/ i" L- c- F4 f% r
  401. /*                                                                                                                                                */
      E% v. P! A9 c4 _
  402. /* Returns:                                                                                                                                */
    * {  o. q% l/ B; W6 e' N, f
  403. /*                Nothing                                                                                                                        */
    / ]; g  p$ N" `- V; [
  404. /************************************************************************/
    - }% p0 t6 X0 E6 ?
  405. void WREN()6 Q. _' V2 k4 n5 Z* C
  406. {- {8 Z+ _$ q8 R  d4 R- w
  407.         CE_Low();                                /* enable device */7 S* F2 L  \! T: }8 `" I
  408.         Send_Byte(0x06);                /* send WREN command */) L: a# f" l+ g9 R' v+ _1 Z$ c
  409.         CE_High();                                /* disable device */; I4 o& Z$ q1 F: F6 I1 p( a" d3 f
  410. }
    + T8 U9 ~9 F" I( C2 m6 S( r" m

  411. . l+ \: N) J* Y9 c
  412. /************************************************************************/2 \; Q9 b* F$ n6 I0 r8 j
  413. /* PROCEDURE: WRDI                                                                                                                */2 n* V' d5 ]" P# ?, S# }. s& V
  414. /*                                                                                                                                                */
    , x$ {6 n+ |6 q& u; a& l! O
  415. /* This procedure disables the Write Enable Latch.                                                */
    $ n; Y9 p. Y. I& y# J0 d
  416. /*                                                                                                                                                */
    % C( ^3 g% E- d6 A# e
  417. /* Input:                                                                                                                                */
    $ k+ l9 L; c* [) n3 i+ y
  418. /*                None                                                                                                                        */* K+ Q& j1 K/ y8 E1 I$ Y7 r+ a
  419. /*                                                                                                                                                */
    : T: c! Y7 \* m  |8 m, p3 r
  420. /* Returns:                                                                                                                                */
    8 Z5 R0 n8 ]2 ?- t" U" p7 f) R
  421. /*                Nothing                                                                                                                        */
    & z( v6 n3 L. A% ?2 V; Y3 g8 \
  422. /************************************************************************/
    ! ]: |8 `3 V" Q, T& F, E9 t0 [$ P
  423. void WRDI()
      M$ M- G  F+ Q% _) ^9 w3 J2 Z
  424. {
    4 ^& z( n7 a+ [1 u1 A
  425.         CE_Low();                                /* enable device */5 M9 x3 k4 d! m4 s5 K$ }
  426.         Send_Byte(0x04);                /* send WRDI command */0 [, S0 ^' t- R& P
  427.         CE_High();                                /* disable device */
    * v; l0 N# [  F5 D
  428. }1 V0 S; M4 j* @6 [

  429. 5 m6 r4 s6 B; ]
  430. /************************************************************************/
    $ }% x6 l- n$ T  O+ ]( C" }4 A
  431. /* PROCEDURE: EBSY                                                                                                                */% w1 G5 G$ k( J# V
  432. /*                                                                                                                                                */& M3 G* f8 q" P5 U) L
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    $ E; f. \/ {3 L7 e  s$ ^
  434. /* programming.                                                                                                                        */
    : C2 ?& v# Z2 k, f
  435. /*                                                                                                                                                */
    . Y- J' I! W9 B5 t" Q8 Q2 U- a
  436. /* Input:                                                                                                                                */( c* f1 z7 N6 q% g. B! y
  437. /*                None                                                                                                                        */
    : i! Y3 h$ v) k' t
  438. /*                                                                                                                                                */* G. o& j$ q5 B3 @3 C% G
  439. /* Returns:                                                                                                                                */1 ]2 ~: @4 d7 K* v, I' i+ y
  440. /*                Nothing                                                                                                                        */
    & B% P0 O( G4 }! t+ P8 e& Q; o+ Y/ O
  441. /************************************************************************/; l6 X- F/ R0 E/ q! m2 m" y
  442. void EBSY()" a5 A5 `' m9 W
  443. {" T9 E" t( [$ o/ H$ S5 s
  444.         CE_Low();                                /* enable device */. i+ p$ J; j* E% M. y  y
  445.         Send_Byte(0x70);                /* send EBSY command */
    . s8 ?& `# D% f% k
  446.         CE_High();                                /* disable device */4 q' [0 o5 U% A  V9 ~% l( m
  447. }
    6 U3 V" E" ~  V5 [$ w
  448. . f* F$ p; O2 ]5 v
  449. /************************************************************************/
    & c7 N8 k4 P- ~. N2 A# `1 }3 B9 i
  450. /* PROCEDURE: DBSY                                                                                                                */
    ' ]( J. S6 x" b2 Q+ t7 q/ ?8 u
  451. /*                                                                                                                                                */1 u# l  y3 C+ j: d
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    # ^* t0 F6 X( D. W9 R
  453. /* programming.                                                                                                                        */% _6 h  k: f$ `& g) K
  454. /*                                                                                                                                                */
    % \# }( Y& q1 `7 L6 K
  455. /* Input:                                                                                                                                */% ]& S# |( ?6 M* q8 A* z  `' g9 r
  456. /*                None                                                                                                                        */: @9 j2 c' ]7 \, W0 |* J0 ~
  457. /*                                                                                                                                                */
      n( P8 J. |4 c# `
  458. /* Returns:                                                                                                                                */! G) o& |: E( H: i7 B
  459. /*                Nothing                                                                                                                        */
    3 e8 P3 o0 U5 `' t4 [/ [6 `
  460. /************************************************************************/
    6 U4 Y( Q  T0 i4 S- W
  461. void DBSY()8 U, W3 y9 T# F1 k3 y" B' X
  462. {; ^! H' V% t; D9 ]
  463.         CE_Low();                                /* enable device */* m  B5 s/ X6 }" [, U
  464.         Send_Byte(0x80);                /* send DBSY command */
    ( Y( u: Z/ ~" Y4 c1 k0 ^
  465.         CE_High();                                /* disable device */
    9 @- n; `& [* W: m
  466. }
    % Q0 t( r" Z+ o3 q2 |5 N2 ?
  467. % Z0 z3 T8 f/ u: Z# \& k
  468. /************************************************************************/8 e5 k  a5 w+ Z( Y3 x
  469. /* PROCEDURE: Read_ID                                                                                                        */9 ]: m; [3 v/ j
  470. /*                                                                                                                                                */
    + C: o3 p% _: ]2 n0 T7 v6 Y
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */9 ~( P5 @8 ?# d0 m) i- d
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */+ v/ T& \& W, e6 B+ U+ ?5 {2 H8 ~
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    ( X1 p. G5 E% y( v
  474. /* whether the device outputs manufacturer's ID first, or device ID         *// ~/ k# w' v2 f* Q/ x. z2 K. F4 n
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    # S& r* [3 B( ?+ O" u! H
  476. /* variable byte.                                                                                                                */
    + a( ^0 D( `- {+ |, A- D
  477. /*                                                                                                                                                */8 E. ]# S6 H6 i3 `* N5 v; N2 H0 ]
  478. /* Input:                                                                                                                                */0 s3 {- T/ z7 B1 h. o* Y; u
  479. /*                ID_addr                                                                                                                        */& Y5 I1 `- c; n& ?* m6 F
  480. /*                                                                                                                                                */: [1 K' z4 t3 h5 L% i/ ^
  481. /* Returns:                                                                                                                                */2 ]) F1 G# {1 r( N4 j  e
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */5 U! `# A2 N8 V' }7 [
  483. /*                                                                                                                                                */
    6 R& u) Y8 A0 K2 a/ Z- m
  484. /************************************************************************/% K- s$ i  T5 M; Z
  485. unsigned char Read_ID(ID_addr)- ]2 Z2 N8 k% i9 W. w2 h% b
  486. {6 l/ L' G& m5 v/ f- c' V7 P
  487.         unsigned char byte;* K- k) p: i( u# Z. c7 h  ^! y  O
  488.         CE_Low();                                /* enable device */
    / a) y# z8 `# Y4 I' M
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    & d# F4 N3 d! g
  490.     Send_Byte(0x00);                /* send address */" n. F( J3 F$ R& u
  491.         Send_Byte(0x00);                /* send address */
      w  [& t: z  F  f1 ?2 D4 W; V, ?
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    9 f3 U. w: x0 a1 G! L
  493.         byte = Get_Byte();                /* receive byte */
    ( K4 w! V* e8 T' \9 u
  494.         CE_High();                                /* disable device */
    % z7 ?5 s6 O7 q9 Q; h4 A- N
  495.         return byte;) Y& q9 F, N& [  u0 s' L/ ~
  496. }
    * C" S7 B9 l) I* A8 n/ ]
  497. , n! U6 c4 ]% s1 f
  498. /************************************************************************/
    - E& p0 k& p/ W1 O8 V# K
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    % h3 E  O3 [/ x' `& @' E6 k
  500. /*                                                                                                                                                */
    % C; N  r' i2 |# E
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    - G/ m. R2 P1 @2 Q+ f
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    $ U% A9 r% D+ r$ N
  503. /* Please see the product datasheet for details.                                                  */
    - k' Q, Z+ j* y/ j5 V5 U
  504. /*                                                                                                                                                */& q. o) ?  P1 I$ s1 t5 ]  a
  505. /* Input:                                                                                                                                */0 N, c5 D5 \/ i" \" o) j+ j4 X0 w
  506. /*                None                                                                                                                        */
    0 g+ ~: p# d% D  J8 J( `3 s) J, p
  507. /*                                                                                                                                                */' R8 {$ Z* [! H3 |: k, D
  508. /* Returns:                                                                                                                                */
    % K+ r' w9 g: L; \1 c" Z& C
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
      C1 T$ s5 r" V( _7 l" A
  510. /*                 and Device ID (8Eh)                                                                                        */, r) t: M# ~, Y3 ?& W; T" G+ Z
  511. /*                                                                                                                                                */$ Y; z" u& Y9 v4 [. @  w
  512. /************************************************************************/
    + _# C1 {2 `- Z- ?' a& J
  513. unsigned long Jedec_ID_Read()
    : l3 B0 @. }5 N8 W
  514. {! G0 ~2 L- |3 j0 {
  515.         unsigned long temp;
    4 V. C0 O* S9 A( J9 }( B
  516.         ! X* @# u) J+ e2 w4 c" l% d
  517.         temp = 0;) w3 T$ w  ]) }. F: |  A- \

  518. " ^6 ]4 f/ k+ P4 B7 s4 W- l; `& E
  519.         CE_Low();                                        /* enable device */  F9 F. d3 X6 x( {: g
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) *// U- D- N$ z6 z0 ]# v/ m: f4 A% \
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    - ?0 Q* [# p' A5 o/ q
  522.         temp = (temp | Get_Byte()) << 8;       
    * B0 e0 J; f4 ^* I2 B1 j( {0 d( X
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    3 t% ~% n" ?2 u8 e1 I/ A
  524.         CE_High();                                                        /* disable device */
    8 Z% M$ y0 e; E& B
  525. ( y4 D* V3 S3 B: V6 Q0 j
  526.         return temp;) Y* H2 e, h4 O7 X& `7 m
  527. }; J8 A& Z; W0 Q$ O( u

  528. 2 y' h& K: H, ?: {' R* {
  529. /************************************************************************/
    ; r7 J8 v9 _, S( o% S
  530. /* PROCEDURE:        Read                                                                                                        */
    : {( x7 @3 H) ~/ N2 P& M
  531. /*                                                                                                                                                */               
    8 o" o% C, F1 z6 L4 u9 u. {: A6 T" x' L) n
  532. /* This procedure reads one address of the device.  It will return the         */. _* f2 o: ?, S* w- `. Q: l& o
  533. /* byte read in variable byte.                                                                                        */; E7 \0 h& g% F5 h
  534. /*                                                                                                                                                */
    * a3 l" F, V- G1 d5 H
  535. /*                                                                                                                                                */- y% t% N4 W9 u% K( Y; A
  536. /*                                                                                                                                                */* W! ^7 ?& ]/ I- I
  537. /* Input:                                                                                                                                */
    8 X) A, h/ i& J8 e9 N
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */2 f; R8 F$ q, e
  539. /*                                                                                                                                      */) C: G8 S( q2 q4 t) z* W
  540. /*                                                                                                                                                */
    : ?4 f* R9 y& L+ t
  541. /* Returns:                                                                                                                                */
    / a9 V' e, [- {
  542. /*                byte                                                                                                                        */) H8 d# {6 T+ m
  543. /*                                                                                                                                                */
    2 u( R/ i- @' p, k1 R/ B5 [
  544. /************************************************************************/
    ) O* d( a6 G; i# B" F
  545. unsigned char Read(unsigned long Dst)
    + z8 U0 ?: W1 r; R8 l2 [  ^
  546. {
    6 F0 P' W( [- i" E) X
  547.         unsigned char byte = 0;       
    9 S" p, A3 y. k( H/ @4 i& c0 [8 k7 j

  548.   }8 V+ ?$ [+ I, j+ K) [  l5 @
  549.         CE_Low();                                /* enable device */  r. S! Y" p! A- B' K' V. k
  550.         Send_Byte(0x03);                 /* read command */
    ' u6 P" d. C" u6 |9 |
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ' u5 s. j& |- e8 Z; F
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));. x3 J! |* O7 b( F
  553.         Send_Byte(Dst & 0xFF);7 G9 X/ `+ M5 E. W( M" ?- m
  554.         byte = Get_Byte();
    : o4 W% h% H- ^- e
  555.         CE_High();                                /* disable device */( Y( l/ w; o3 y0 J' l  S
  556.         return byte;                        /* return one byte read */
    4 E2 R2 S' n9 N4 j
  557. }+ A- v& }& Z2 t$ ~1 V1 O- X6 q
  558. ) ~- a  s" Q$ M) [
  559. /************************************************************************/
    ! }2 a, f$ n& ?  L! f6 Z. H
  560. /* PROCEDURE:        Read_Cont                                                                                                */' H7 Y: ^% Y% e' b& b& v
  561. /*                                                                                                                                                */                # u$ p" R# G. v% _
  562. /* This procedure reads multiple addresses of the device and stores                */- P. S- @3 w2 j4 ~7 e! a
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/9 i0 H4 \( A# q9 G
  564. /*                                                                                                                                                */# }9 k, x2 H5 g9 }
  565. /* Input:                                                                                                                                */- j! I8 U8 x  M+ f' x
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    9 d* O* \% _! d6 {
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
      z5 G! L, l/ w! {  D: T& z0 r& G
  568. /*                                                                                                                                                */
    & d* t! k1 ^2 v& B7 L
  569. /* Returns:                                                                                                                                */* t$ v; ]# z- U0 M, `- `
  570. /*                Nothing                                                                                                                        */% a# V& u% G& {! c( h+ U# r& }
  571. /*                                                                                                                                                */8 H+ ]) f0 |/ v" B% g! t( l7 e
  572. /************************************************************************/
    & `' u9 \1 R  H4 W, _  s* ]
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    ; Z" |' g" J6 g  i6 z8 ?
  574. {
    ( S; d3 K+ B; w3 u# Y% z
  575.         unsigned long i = 0;
    ( |5 i9 P* C1 A3 _* p
  576.         CE_Low();                                        /* enable device */
      }. j, ^! G0 d5 m
  577.         Send_Byte(0x03);                         /* read command */
      m* m( e5 O0 Z2 t, p" I% e
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */  a. O! g% ^2 ^
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));$ a4 K- [: t; R9 h0 e8 z
  580.         Send_Byte(Dst & 0xFF);
    6 S/ a9 ~" ^% D7 y, }8 M# t# Z
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */6 u$ W# s3 R9 q; M9 b2 T: T
  582.         {
    , H+ G, p* d0 Y' q
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */2 i, r; ^) d! }2 q+ N/ L
  584.         }
    2 L) Y* h% o! V- {& ^
  585.         CE_High();                                        /* disable device */# p0 A; H$ Q5 s8 \' Z" i

  586. ) S7 p/ Q  M" i+ S5 }3 X
  587. }8 e' p% L4 e0 ~2 m

  588. - {4 M9 t6 G9 `  \
  589. /************************************************************************/
    # Y; s( Q- z4 e- D5 {
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    # U0 e! I$ k: m7 o- }
  591. /*                                                                                                                                                */                ( O6 A+ q. ^. ]$ A
  592. /* This procedure reads one address of the device.  It will return the         */( t0 U8 ~. {  Y/ W% ^' W5 r
  593. /* byte read in variable byte.                                                                                        */
    2 e6 |$ l/ H) S" T- m: Z$ |
  594. /*                                                                                                                                                */
    ( X$ V! ~8 V3 M2 k+ g' a5 p1 s) |# o
  595. /*                                                                                                                                                */! b& `/ B- Y2 @2 a  V6 x
  596. /*                                                                                                                                                */$ e: s) ^% q/ S' h, k" D
  597. /* Input:                                                                                                                                */
    , X& b; C5 E6 A+ H" B) _  p
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */# d( ?3 ?0 M7 a$ d
  599. /*                                                                                                                                      */
    5 D3 `! e( \4 M) M6 j
  600. /*                                                                                                                                                */3 K+ i* r  X% V$ T  V5 n
  601. /* Returns:                                                                                                                                */3 w4 A! x% e! }1 ^3 u0 @' R  k
  602. /*                byte                                                                                                                        */) E; Q2 v) n( d; F/ d
  603. /*                                                                                                                                                */% q  A, K& a7 G. e
  604. /************************************************************************/
    9 j  t- E3 I. e6 a, u! @0 ?
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    ! R/ n; ?1 f' {1 W( t
  606. {# {* Z1 B! Q7 p. R/ M
  607.         unsigned char byte = 0;        6 W: B6 |2 g: y# i: X; P4 f7 }& U! N
  608. " |/ ^; {" B' X8 d  S; Q6 v; P) e
  609.         CE_Low();                                /* enable device */) A. W4 Y0 M; n3 V- c' z; A
  610.         Send_Byte(0x0B);                 /* read command */8 E1 f0 l: l3 |- Q# {3 v& }7 ?  m
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    3 l6 @4 W, ^4 @( Y; @3 ?
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ; f. x. F* B$ ~+ w8 R  F+ T5 K6 a
  613.         Send_Byte(Dst & 0xFF);
    : L8 ~5 A/ n' Q& h2 B9 k/ q9 y
  614.         Send_Byte(0xFF);                /*dummy byte*/
    7 X3 V! z$ m0 {" Q
  615.         byte = Get_Byte();
    ' Y2 f) M: |* y# p
  616.         CE_High();                                /* disable device *// d# T( V2 w+ w! {. M
  617.         return byte;                        /* return one byte read */
    - J$ w% ?& l, P3 |* ?% c1 ^! k3 S$ {; [
  618. }5 K1 z; ]& G  m- `7 b

  619. 5 A  q" v$ B4 A% Y2 S3 F
  620. /************************************************************************/
      w  I6 q. Q: e( `
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    - O8 X/ _- @% T/ C
  622. /*                                                                                                                                                */               
    / p& R# `! `0 X9 [8 l0 L; o
  623. /* This procedure reads multiple addresses of the device and stores                */
    7 m, y2 |6 A" n: W7 ?( r( n% W. z
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/' Y/ L+ p8 L! D: w
  625. /*                                                                                                                                                */8 a( @  U0 h& x9 p' w  Q
  626. /* Input:                                                                                                                                */
    * j2 e2 N6 P  h8 Q0 @
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ) C. o; ^$ }; T# {) V
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    # D! N5 w, B: h. p* Y! f! o: G
  629. /*                                                                                                                                                */! O( T6 A) `' a) E4 h5 \
  630. /* Returns:                                                                                                                                */9 C* Q5 X* Y% A! U) I" Q
  631. /*                Nothing                                                                                                                        */
    * B. }. H( D& C0 w! P
  632. /*                                                                                                                                                */0 }0 m! G! z2 h; r* ?9 n
  633. /************************************************************************/
    . Z8 u; F1 A' [0 w  f
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)# O8 U- t3 l9 w# Z7 j
  635. {5 P# _" v* v% }/ T* A
  636.         unsigned long i = 0;+ D3 B7 ]) }6 @7 s- Y6 x5 q# ~
  637.         CE_Low();                                        /* enable device */3 K: y6 k! o& p# ^, ?" T! X
  638.         Send_Byte(0x0B);                         /* read command */& c  a( Q9 `9 S$ n# J* \, Q
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    & @& ~( p8 I1 C% F; `6 o4 m
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ( R- L7 G9 ^# @8 D
  641.         Send_Byte(Dst & 0xFF);
    * x6 v( Y; p- n9 H3 Q
  642.         Send_Byte(0xFF);                        /*dummy byte*/
      R7 {, I3 r9 w( a( c8 i
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */# m9 h0 t( t6 v0 R- b8 h
  644.         {. j5 h9 h& J# o# ~
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */; s3 ?* E9 L: Z; X8 c, y6 e) _: R
  646.         }# U3 L* k' p4 B3 t! L4 H9 x
  647.         CE_High();                                /* disable device */
    % I$ k/ }0 p+ S$ b1 |/ |2 s
  648. }* F$ \5 D! W" _  j9 j" t; f9 a7 p

  649. , K" i8 z; r0 K
  650. /************************************************************************/* s; K( \& j. M7 U; c6 c/ h
  651. /* PROCEDURE:        Byte_Program                                                                                        */- H" z- Z7 S' M6 R: l8 [. Q
  652. /*                                                                                                                                                */$ B2 u" D* p8 _) ~: `
  653. /* This procedure programs one address of the device.                                        */7 q0 L( }2 Q: n' j/ M
  654. /* Assumption:  Address being programmed is already erased and is NOT        */) j) }3 T& a  ^' b% @- t! x
  655. /* block protected.                                                                                                                */
    / b$ ]0 `9 o" Z/ _" j9 f
  656. /*                                                                                                                                                */6 Q0 L8 @: B0 w
  657. /*                                                                                                                                                */8 k! H+ ~% J( p
  658. /*                                                                                                                                                */9 b0 s& t+ X$ W3 }2 ?% C
  659. /* Input:                                                                                                                                */
    # [' n4 F# {% m! d
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */+ P; Y) H$ x0 A9 _) j$ n
  661. /*                byte:                byte to be programmed                                                                */  E4 A" I" v+ C# G
  662. /*                                                                                                                                      */5 j* F' R& k1 Q, x( _: l7 P" K
  663. /*                                                                                                                                                */5 r9 ~8 H$ I3 V1 z- T6 _" K
  664. /* Returns:                                                                                                                                */. V# T3 U+ X2 L# U/ b2 a
  665. /*                Nothing                                                                                                                        */; k6 \$ Y& y# _: h( X2 M
  666. /*                                                                                                                                                */
    4 P  W; w3 O8 U8 P! n( `" g
  667. /************************************************************************/
    ) k) L4 ?9 `# c: T6 j
  668. void Byte_Program(unsigned long Dst, unsigned char byte)( C1 X$ h0 y/ e. h) ?' \$ b
  669. {
    & j* P2 k4 T+ h. ~: x1 F/ q
  670.         CE_Low();                                        /* enable device */" o& k+ S' @+ j; ^: R# q7 ~/ i' G
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    3 [. h9 `, p. a7 _6 [" B6 o% k
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    , {! d$ n. c) ]
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 ~; q# F  D4 {: w3 C& Q
  674.         Send_Byte(Dst & 0xFF);' J9 m! R+ b8 A& w* U" G2 @
  675.         Send_Byte(byte);                        /* send byte to be programmed */- |) K# H1 T9 t, f  b4 {  }
  676.         CE_High();                                        /* disable device */0 L2 j- A' x1 N6 p  l; X7 ~
  677. }
    : z; F. I+ [: Q0 t

  678. 7 V& R* f0 X8 ~0 l2 a
  679. /************************************************************************/& ^! v: }* I0 j- n: L& N
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */4 e) \& v) d. K4 \  d, E  g7 U
  681. /*                                                                                                                                                */
    4 |# ?' W8 }1 C4 j# B8 t% P# O. K2 x
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/( \. X' ]- @* a) j
  683. /* the device:  1st data byte will be programmed into the initial                 */
    ( E/ ^8 ]' ]+ r- Q6 B8 f: I
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */$ Z2 V: C+ ]0 L! ~# s% m  g* v
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */+ {/ O1 O# g, N: T9 l9 X
  686. /* is used to to start the AAI process.  It should be followed by                 */# U3 X7 ~( y- B/ v7 p; E
  687. /* Auto_Add_IncB.                                                                                                                */
    0 v( x' P& `4 \! a" ?/ L0 W1 K
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    " y3 H$ M! e' w/ n! M6 B' e$ F* t
  689. /*                                block protected.                                                                                */3 Y. r! A/ z& V5 U
  690. /*                                                                                                                                                */
    4 [7 Q( B1 ]+ a  F" u7 ^$ r4 K
  691. /*                                                                                                                                                */
    ! o+ D' F- h- R' |$ Y
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    . q0 g+ x. @( P3 x
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */+ m7 q* F1 C* d$ j
  694. /*         unless AAI is programming the last address or last address of                */6 F+ d( R# h  J$ k. i1 u: V
  695. /*          unprotected block, which automatically exits AAI mode.                                */! Y' q0 K: y+ m. p) O5 w6 V& d: F
  696. /*                                                                                                                                                */
    ) B. G( V' i$ i' J
  697. /* Input:                                                                                                                                */) w( H& x: b% \& O) R- J
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    % _5 Y; Q1 q4 J7 `& Q* O
  699. /*                byte1:                1st byte to be programmed                                                        */
    # u& ^/ l* q7 _  m' `0 b6 T
  700. /*      byte1:                2nd byte to be programmed                                                        */9 }+ ?0 \8 @- W
  701. /*                                                                                                                                                */" [8 `5 @2 v6 H( n6 M9 m
  702. /* Returns:                                                                                                                                */4 j  [* o% W5 g/ u
  703. /*                Nothing                                                                                                                        */
    - ^" f$ P% {7 J8 X3 n
  704. /*                                                                                                                                                */7 R, {% x' f. I1 E4 S
  705. /************************************************************************/  C/ j. v5 s) R  z5 y6 w
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ! V( V- `- ]4 w3 J' J2 Z1 }
  707. {
    + a4 U  I) o. p6 _
  708.         CE_Low();                                        /* enable device */. R# ?5 d/ a, ?0 D1 [: G" ?
  709.         Send_Byte(0xAD);                        /* send AAI command */
    2 T' N( `" z7 i9 n- g3 q" y% N
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */9 i" r8 W3 G# y
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));3 O$ d' `3 s, V% X/ K. A9 k0 O
  712.         Send_Byte(Dst & 0xFF);% C, n2 O6 h  T! I4 {. K, h$ H& \
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        9 t7 h2 G" l  E5 U
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */5 g- m0 J4 p4 u5 U; h% g
  715.         CE_High();                                        /* disable device */8 U1 N. J( [& ]% |% q8 A
  716. }
    * M+ ]* o) D' T8 z2 F  R% Z
  717. + K( t4 Z$ r& C) o: ~  P9 a
  718. /************************************************************************/
    + ~: R: U8 h( _% q
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    - J0 B* @2 f# Q$ ~, ^" V
  720. /*                                                                                                                                                */  ?2 m1 Y: r0 V7 j4 t
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    $ f2 w% _7 _8 U* _6 R
  722. /* the device:  1st data byte will be programmed into the initial                 */. |- q3 O: ~2 j9 B
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */0 a8 P9 c3 K0 W' F! d! ~' w9 U
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    6 O* z& e3 C, c4 `, r1 Y
  725. /* is used after Auto_Address_IncA.                                                                                */
    0 B& D: t! Q$ C5 D  l
  726. /* Assumption:  Address being programmed is already erased and is NOT        */' l) D! B9 ~; X
  727. /*                                block protected.                                                                                */, ?' e3 O- I7 C( S2 x' ~9 ]- z& e
  728. /*                                                                                                                                                */
    . N$ z( P5 q' t% s% n
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */( R9 L3 v' n+ F6 v4 Z% J
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */) ?0 N  r/ }7 D+ Y# T9 K' D4 b  a
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */; A, l: _3 T- u% b. x4 f
  732. /*          to exit AAI mode unless AAI is programming the last address or                */+ R' q. t% e% |7 ?% L% v+ p3 S1 m8 K
  733. /*         last address of unprotected block, which automatically exits                 */0 [( S" [4 a7 c. J
  734. /*         AAI mode.                                                                                                                        */
    4 W9 R: X0 a7 m$ Q: }: f
  735. /*                                                                                                                                                */
    " q. n, H( Y! P8 ]5 h
  736. /* Input:                                                                                                                                */
    6 k$ T8 x! n. O( O/ b. o
  737. /*                                                                                                                                                */
    0 o2 U( [7 k: v0 ~$ B0 [
  738. /*                byte1:                1st byte to be programmed                                                        */
    ! \7 ^+ J) v/ B5 V2 Y- l
  739. /*                byte2:                2nd byte to be programmed                                                        */
    7 T3 }7 t# o6 K
  740. /*                                                                                                                                      */
    + b( ^. g! D% j5 @
  741. /*                                                                                                                                                */0 O! p* J7 n- u9 Z5 b! v
  742. /* Returns:                                                                                                                                */( K3 I7 \- ~" x4 A4 r
  743. /*                Nothing                                                                                                                        */
    ' K9 c! g8 i. Y
  744. /*                                                                                                                                                */" w0 U8 O9 g: ^) p! z$ `" R
  745. /************************************************************************/1 x- k* u( T" x' O6 I/ F8 w
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    $ f( U1 q: T  t6 D. Z' x8 j) t) v
  747. {
    ( ~7 o4 v5 o4 Q0 U' g2 o/ `
  748.         CE_Low();                                        /* enable device */: `6 ~" U6 J1 f2 w
  749.         Send_Byte(0xAD);                        /* send AAI command */
    9 y3 i$ y- [+ d/ A; P- \' t6 B8 `
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */1 z9 L2 h2 J3 b2 p' @% \
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    * O3 l' |* L. ~1 Y
  752.         CE_High();                                        /* disable device */( {0 ^) o- @: i6 n7 Y
  753. }* P- S, M5 l/ ~. h# x7 {1 k

  754. 5 `9 [5 [, |# ^4 v7 @
  755. /************************************************************************/* N2 K, _4 i0 x- T" U) o, u
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */$ \) p7 T4 y& V- s/ U
  757. /*                                                                                                                                                */9 k+ l+ V3 W3 }! a3 Y$ |, q
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */; M3 t" I3 ^6 m. J9 m
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */! `- b: n6 O! Y# _  R
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    ' i2 C1 |5 e. p" ~
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */. O3 Q+ I9 g. U: V. e2 {( \) I$ {  l
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    1 u0 b$ s0 _( {/ F$ c6 f! B
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    + y# u: @8 [2 @! V1 S
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    $ u+ j% n, A3 d3 |9 _
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    : ~  e, ~' j, i& c
  766. /*                                block protected.                                                                                */. g% N' T+ f. X5 [; a% _, Z9 n
  767. /*                                                                                                                                                */
    % h+ B8 h/ D  W  V4 X1 e1 q  J
  768. /*                                                                                                                                                */
    $ X4 k! U0 r4 x) k! N/ S; S8 Y
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    # M; S$ j1 k6 O
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    5 J$ U% j( t7 ]) X4 p9 S  O, o
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */; Q. d: p6 @/ D" `7 v
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    0 h1 E& q; C! u1 b  n
  773. /*         last address of unprotected block, which automatically exits                 */! d4 Q- f7 a. z* G. n
  774. /*         AAI mode.                                                                                                                        */1 L5 V2 g) o# ]/ b6 G) q7 [7 s
  775. /*                                                                                                                                                */; E: q1 A6 U* m0 Q. Q$ j9 d: s7 O
  776. /* Input:                                                                                                                                */; C5 E  f( e& G) H
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + z  [# P. D4 @# I5 x
  778. /*                byte1:                1st byte to be programmed                                                        */: Q( M6 x( k  I
  779. /*      byte1:                2nd byte to be programmed                                                        */
    * ^1 Z& @2 y; J. h. F6 T+ f9 w1 l; X
  780. /*                                                                                                                                                */: H' Y1 [0 N- G, M2 W' o
  781. /* Returns:                                                                                                                                */2 I# g. ^# c/ p/ P2 O; g' T3 w
  782. /*                Nothing                                                                                                                        */
      c3 W! R3 |3 R1 t9 T  q( p+ V
  783. /*                                                                                                                                                */1 J0 @% U4 l; r+ K& P
  784. /************************************************************************/8 M" o( Q1 x1 G& Y( i. L1 ?* S
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    3 `2 f, T% U# R# h! D- G
  786. {: Q8 T6 }: i2 W
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        , f6 a7 A4 U) @

  788. 9 D" U9 [- q5 S) f. J' r, p' a- |" S$ a
  789.         CE_Low();                                        /* enable device */
    # [* X6 U7 l+ p3 s0 f7 ]
  790.         Send_Byte(0xAD);                        /* send AAI command */% G+ \( e  w/ o0 P
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */% J/ d' L# Z: I3 |. D$ m
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    2 p2 x( Y. s  W8 k
  793.         Send_Byte(Dst & 0xFF);: u5 I7 s& K1 c2 r* ^
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    # r- {' U! ?) j2 d& t7 ]* P
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */, o& W* e6 h% L2 m8 U2 i
  796.         CE_High();                                        /* disable device */
    4 Q& c4 f$ P+ G$ t( L3 {* M4 ]
  797.        
    . e5 _: v9 }+ \3 b9 m7 U* a
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */# G6 y5 f. d6 s9 M
  799. . o! B. g) N7 V0 G
  800. }1 ]8 b7 l4 I5 U) r/ V5 ^! q/ F0 W
  801. 6 s+ P9 C: O+ {- x
  802. /************************************************************************/, Z6 ?8 [2 b: e. [4 X% j' ^
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    ) V* ?" A# o* P, o
  804. /*                                                                                                                                                */* _$ Q( b' o/ O+ R) k
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */8 S+ r6 L1 V, e2 [: h" J
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */) n1 d$ a7 ?+ O; G4 P4 `
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    7 x: Y% p4 Y0 |  W4 e
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    & {4 l) e. l) O/ F. X4 R2 o- l. }
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */6 g4 M* z4 d& \* j: L. t8 p
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    4 {) _2 N( K$ y8 Q
  811. /* used after Auto_Address_IncA.                                                                                */
    ' L- k* f0 K4 h+ B
  812. /* Assumption:  Address being programmed is already erased and is NOT        */! {; \9 ]' \5 C
  813. /*                                block protected.                                                                                */, z8 f& B& K" ?% @% B% d0 G6 H, U
  814. /*                                                                                                                                                */
    / w1 s; X5 r2 O8 T& }: R  L9 C
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */( I6 Q9 Y1 V8 I
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    / A7 c. B9 G9 k, ^
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */. p0 e3 w- |# I9 l
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    0 ~1 s6 }  M4 C5 B* @+ n* E8 n( y
  819. /*         last address of unprotected block, which automatically exits                 */, d6 c3 O- e$ d. a  j
  820. /*         AAI mode.                                                                                                                        */
    2 @* z3 M( t2 Q& K+ D
  821. /*                                                                                                                                                */
    9 v+ o/ m; j1 |1 f
  822. /* Input:                                                                                                                                */% R7 g+ c& ?, k$ {/ M
  823. /*                                                                                                                                                */
    , P. g& V8 K- k; J2 p. x$ [
  824. /*                byte1:                1st byte to be programmed                                                        */
    4 c# E3 r- s6 c7 K
  825. /*                byte2:                2nd byte to be programmed                                                        */8 N. m; R, N0 a% B
  826. /*                                                                                                                                      */( r. d# z% W0 c  o
  827. /*                                                                                                                                                */
    / H: _2 B, l4 B! [3 F
  828. /* Returns:                                                                                                                                */
    # l/ t; E$ }: h( l0 z5 ]
  829. /*                Nothing                                                                                                                        */
    & t5 @  F$ I( |+ a
  830. /*                                                                                                                                                */3 v, W! o4 A+ O
  831. /************************************************************************/5 o" R% z3 _- ?' a  Z' w) Y
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)+ C4 J4 d# `5 D( L% K4 C* s
  833. {( D; ^3 X, k( ]2 R5 l9 q" }& x
  834.         CE_Low();                                /* enable device */6 \% l7 `" Y: K& K7 u
  835.         Send_Byte(0xAD);                /* send AAI command */; ?" E5 {  Z4 H$ \  m2 n8 c4 \+ I- A
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
      M% c' v+ R* _. W3 y9 x2 C
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    & O, U- U& Y) }! i; Z4 d) w1 M
  838.         CE_High();                                /* disable device */
    : ^; W6 l  m- m. h
  839. 2 J. |( }6 ~  ^" f6 u$ |
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    + i/ p: G& I2 S' L) \  p1 G8 U" c. z

  841. 1 k$ i: f. X+ Z- ]  K
  842.         WRDI();                                 /* Exit AAI before executing DBSY */+ X1 O7 ?+ j7 ?& I7 t6 w5 C! B) J
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */2 t) f5 q; v; k8 p5 l0 ]% M9 n
  844. }
    , V; q8 n, t# H* g( b' X
  845. + a6 Y9 Z" Q4 H3 c$ ~  m- D# d5 ~( L
  846. /************************************************************************/! J: z/ n4 K; z# ^, C; k
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    - T7 D3 Z& ]; L& ], A
  848. /*                                                                                                                                                */6 l/ s( g3 D- _5 Z
  849. /* This procedure erases the entire Chip.                                                                */( N1 H0 R# q; l/ r* _
  850. /*                                                                                                                                                */9 b7 t7 s7 t2 u4 u: a! ^
  851. /* Input:                                                                                                                                */: c$ `0 S& f4 O
  852. /*                None                                                                                                                        */' s1 i% m7 d- b8 t% r# C
  853. /*                                                                                                                                                */4 N4 a8 w: B8 V+ q8 s. w& Q
  854. /* Returns:                                                                                                                                */
    4 P# o1 J8 G. j) s0 n
  855. /*                Nothing                                                                                                                        */
    6 {* I, R3 N# L* Y& H! U. ]; G0 h
  856. /************************************************************************/
    & f7 C) I6 G! D# C. j8 F
  857. void Chip_Erase()
    1 u9 B# ^- t+ _! \
  858. {                                               
    - t* o/ v" R" h
  859.         CE_Low();                                /* enable device */
    1 d  j& d4 I+ f& G5 p' m/ M: J0 e, o
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    9 p- K; L) y$ e5 _* R8 C
  861.         CE_High();                                /* disable device */( N5 A; ?! J0 }- @/ Z; }" A  R
  862. }  a7 {) R+ V) I! d) h- I5 ]: m

  863. 7 a0 S5 u* _+ H, m) P+ E  \  g
  864. /************************************************************************/
    / H6 z: _6 r) Q4 \% b
  865. /* PROCEDURE: Sector_Erase                                                                                                */# h/ x+ {$ `9 A' ~0 Q* R
  866. /*                                                                                                                                                */
    * U% @& f2 A/ D& h% u; S1 h
  867. /* This procedure Sector Erases the Chip.                                                                */& f2 g/ p& c. t: x7 i
  868. /*                                                                                                                                                */
    6 n: h, f8 @4 m7 I7 X
  869. /* Input:                                                                                                                                */
    ) E7 w8 K% h' J$ e9 C7 P
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */: ]3 P4 v9 c: O8 {1 J5 w
  871. /*                                                                                                                                                */" @- h9 N7 Z9 x( O- k2 O4 d/ ~6 [( @
  872. /* Returns:                                                                                                                                */
    7 m, x" A* X" D; N, z
  873. /*                Nothing                                                                                                                        */4 }8 E' p% {: B/ ~' s: d+ F
  874. /************************************************************************/& G' u! T6 A  A/ I3 F2 c+ s/ y
  875. void Sector_Erase(unsigned long Dst)( @$ R* x0 |! E% ]
  876. {2 w) Y; }# l- R. r, H1 d; [

  877. % e8 S! f6 X8 l

  878. 0 Z8 d; M8 d# f" P( M3 s
  879.         CE_Low();                                        /* enable device */
    8 \9 S9 t% d! U1 B. g8 k
  880.         Send_Byte(0x20);                        /* send Sector Erase command */  Y6 e! L  `) i1 n* u
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    7 V5 a# s4 R0 t' H- A! F- g5 ~
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));$ Z% O2 n2 }6 O
  883.         Send_Byte(Dst & 0xFF);) F* Q& z5 w: m/ E
  884.         CE_High();                                        /* disable device */
    4 ^( x' K& |- x% y. ]. y4 _
  885. }        1 m( o0 O. w$ w5 B$ g* U" Q

  886. . F) r5 \! v% D6 {
  887. /************************************************************************/
    ( `, h' S) L' c6 N3 w1 ?
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */3 n3 T6 v9 T1 ^* S8 b4 g
  889. /*                                                                                                                                                */& q, L9 j& a& \* L) Q" m1 b
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    . [" F; h! r8 r" O) g" E
  891. /*                                                                                                                                                */
    5 Y$ N. L1 H: j
  892. /* Input:                                                                                                                                *// n/ I- a% l5 J# q$ ?* F
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    / Y9 n. C( |$ C9 r9 X
  894. /*                                                                                                                                                */% T" t3 e6 B* j+ S7 @# }: w
  895. /* Returns:                                                                                                                                */) j8 E6 B1 k1 r
  896. /*                Nothing                                                                                                                        */' r) a( R; R. s  i
  897. /************************************************************************/
    . a9 w, Y2 t5 q: Z/ p4 d7 Y) z
  898. void Block_Erase_32K(unsigned long Dst)
    ( k/ j' T+ L. R4 ^( u
  899. {4 \8 M0 t& @- ]
  900.         CE_Low();                                        /* enable device */7 T5 M0 P  }6 {7 q+ h: a% k+ W
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    8 j' Q& d  v( |
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
      c, Q& ]2 _8 |  {' |6 }/ ?
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));, j: |3 s/ \, h0 Q$ B7 p7 K3 A: z; j
  904.         Send_Byte(Dst & 0xFF);
    6 _2 q) f1 W8 |8 p
  905.         CE_High();                                        /* disable device */* s  n: z! C. |) h8 `& Z
  906. }
    5 u  o1 I/ R  Q6 g
  907. ! H1 M7 |4 q- P6 A
  908. /************************************************************************/% O2 G& E7 F/ O# f$ F" l" d, H
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    + O- m8 k4 m& L1 M9 O+ |
  910. /*                                                                                                                                                */
    + P1 F) y6 y; f1 ^8 f" Z
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */  j7 `  o' s% D* n5 j. }
  912. /*                                                                                                                                                */
    $ Y3 ^2 m( I; |* o1 P
  913. /* Input:                                                                                                                                */
    ! \- ~" A$ q! F8 a7 A4 ^8 G
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */$ |8 u; j2 I& {/ w- A$ {5 d
  915. /*                                                                                                                                                */
    0 o$ Y: @, K3 b; f
  916. /* Returns:                                                                                                                                */# E* E, R1 N* `& r' s! L+ s
  917. /*                Nothing                                                                                                                        */( \  G# a2 R; q
  918. /************************************************************************/$ K% b9 ]; ~+ w8 b$ X
  919. void Block_Erase_64K(unsigned long Dst)
    * ]  H) G% V- \, |2 \
  920. {6 ?% d; ^8 l9 A+ o
  921.         CE_Low();                                        /* enable device */
    * z. U. v) L7 o, {) H+ B+ Y0 P7 e
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */& s* d% C; D9 G# e1 x  p
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    # D) W6 g$ E3 L( m- ^* }1 r1 ?: _
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    2 o9 b) G5 b' L, d
  925.         Send_Byte(Dst & 0xFF);
    % ?3 X- G: ]# ]3 r1 r5 s$ L( j
  926.         CE_High();                                        /* disable device */3 S7 `9 b) {5 T3 E6 _$ c8 E, _. U' o$ ~
  927. }
    ' s' U  V5 {. r, l/ j
  928. & s* i; B% x* J$ c+ R
  929. /************************************************************************/3 Z9 _2 s  U! D- R6 K' [5 H
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    " u# q0 T- j2 l6 }0 @
  931. /*                                                                                                                                                */
    & A; S5 F5 F( \2 l
  932. /* This procedure waits until device is no longer busy (can be used by        */
    + D8 c2 D, U+ @
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    " q3 {' n$ @" O; R
  934. /*                                                                                                                                                */- @+ a: U  i) [9 q- i5 a& _  w
  935. /* Input:                                                                                                                                */
    ) s! B* B9 x5 _, X  w3 z) o( d
  936. /*                None                                                                                                                        */" W5 v( k1 F- d9 H5 w6 A* A
  937. /*                                                                                                                                                */: A2 Y0 h2 U- H
  938. /* Returns:                                                                                                                                */+ t7 @5 z, Y& t6 o7 U
  939. /*                Nothing                                                                                                                        */, F- n$ i9 p; F+ }2 m
  940. /************************************************************************/
    8 u. Y( @) y' {; J5 l3 g  V  g; j
  941. void Wait_Busy()
    . l) O/ L* I8 L6 i) P8 x
  942. {/ O9 ^5 S; a- ^0 b% d# \
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */- h0 p- n" V1 T8 u$ G) p+ _
  944.                 Read_Status_Register();7 O/ _2 f6 q. _! k* G" S, P5 }
  945. }
    8 r) A" L5 ^3 U9 [8 c# G. C

  946. # o8 R$ a7 v5 _: {: L) Y
  947. /************************************************************************/5 D1 }1 w/ ~- G
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */* J1 K4 F. e6 R  W  d
  949. /*                                                                                                                                                */
    ( n% Z; n; G2 l2 k
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
      {8 x9 B& o+ n+ B& U/ w
  951. /*                                                                                                                                                */- |! D/ o+ v4 P) j0 T! t
  952. /* Input:                                                                                                                                */
    % `+ D- [7 Z( N! N1 e% s# W  ^
  953. /*                None                                                                                                                        */5 I6 n/ r& n" k! s& P+ L  m4 V
  954. /*                                                                                                                                                */
    , s" ]7 T& Y% O
  955. /* Returns:                                                                                                                                */
    % T$ e/ N3 T" A
  956. /*                Nothing                                                                                                                        */7 h- q; l& n2 R
  957. /************************************************************************/
    , A5 z/ l6 a' K" t& L) D$ Z
  958. void Wait_Busy_AAI()
    9 u; ~. O1 \3 V+ c
  959. {
      e- A0 O/ s+ C; a
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */7 C7 s. O, G6 f' V* c" |
  961.                 Read_Status_Register();, C0 G  z" S0 B' F. r: F0 C! [
  962. }
    $ q, J: _" i: l% r! J" b
  963. & g: e# A9 Y) m* l; y3 K" L. z* ~6 x
  964. /************************************************************************/
    2 d* W! p; Y- E6 J6 Y) a$ X1 }% W
  965. /* PROCEDURE: WREN_Check                                                                                                *// R6 n2 K/ J1 f# H0 Z7 T
  966. /*                                                                                                                                                */
    : c# s3 X& `4 ~
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    ! x: R. C! l" m4 [
  968. /*                                                                                                                                                */
    & c" o, o/ @: n5 Q2 g+ ~, P
  969. /* Input:                                                                                                                                */: v5 E& o- p7 P. z
  970. /*                None                                                                                                                        */
    " P2 C& f% P4 K2 m- [: Q2 ^: ^
  971. /*                                                                                                                                                */
    9 N. j7 t1 n  T, G! t
  972. /* Returns:                                                                                                                                */
    3 X* v& ^4 @! c2 M) {
  973. /*                Nothing                                                                                                                        */
    4 X2 t, U( a! k
  974. /************************************************************************/
    0 [! x' S/ n) T: |( f' L
  975. void WREN_Check()
    . h7 p/ v, P, ?: F1 z) o4 s
  976. {
    , ?" H4 j- V; F! A7 m: O& k$ p- p
  977.         unsigned char byte;
    ' Z9 i$ r# S2 J* _, d
  978.         byte = Read_Status_Register();        /* read the status register */
    & Z; M% v2 J; X/ l8 a4 X" A
  979.         if (byte != 0x02)                /* verify that WEL bit is set *// t6 y( F8 A& A5 n4 G0 q
  980.         {
    7 d0 _& P2 U! o( J
  981.                 while(1)* G  Q& }7 }/ N3 w- z& F6 i; E
  982.                         /* add source code or statements for this file */
    2 B: n2 z; r5 f" p3 i8 {0 n3 ]
  983.                         /* to compile                                  */
    # u& ^( ]: }+ V, ?' o6 |
  984.                         /* i.e. option: insert a display to view error on LED? */+ a2 f8 I/ x6 E  O2 ~
  985.                  
    - p  q$ X# R; n. ~
  986.         }
    ' U/ h7 Y8 @. Z. u5 R( [
  987. }
    2 B) D' ?: x6 _# n+ N, o+ O

  988. + x& c7 i* ?2 V, X9 M
  989. /************************************************************************/$ S: I. _: t- i6 h  U! Q
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */) Y8 o; w/ H( B1 z
  991. /*                                                                                                                                                */' e7 Y! j7 a, z6 J( q4 J
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */( f5 m% p# I$ p+ Q! q7 k. I: z
  993. /*                                                                                                                                                */
    . i/ o' X: x5 W' z: k, C
  994. /* Input:                                                                                                                                */
    8 o/ e- H9 ^9 J3 Y+ A
  995. /*                None                                                                                                                        */
    ! U# g! h( U0 e( _% n. e9 L7 X4 P- v! T: r
  996. /*                                                                                                                                                */* j2 B0 e; J4 c3 w+ O  v
  997. /* Returns:                                                                                                                                */
    ) Z- R. _* C8 h/ q; @& H4 D
  998. /*                Nothing                                                                                                                        */
    & A7 Y6 S+ x4 b! c! V
  999. /************************************************************************/! g. }' C; S% M, M: `3 W
  1000. void WREN_AAI_Check()
    ! Z) n% j# T1 T" U3 k- D0 w
  1001. {
    + a' g( s. R1 G: Y  ]
  1002.         unsigned char byte;
    / w; b# P8 t* e: v5 k* [! q
  1003.         byte = Read_Status_Register();        /* read the status register */
    - W+ ^3 R! O' Y  i0 c. K( W% b
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */* k7 a/ v5 B+ L2 K& J$ x$ F
  1005.         {
    / x7 C: z* }) r; l
  1006.                 while(1)               
    6 f9 T7 d0 {2 t( n. D
  1007.                         /* add source code or statements for this file */
    % D% l4 a# a8 s4 z5 V  y
  1008.                         /* to compile                                  *// M  v1 W. e7 m* M% O) Z
  1009.                         /* i.e. option: insert a display to view error on LED? */
    0 u. k/ t; I) x3 W
  1010. & P9 r' Y: K4 d$ `
  1011.         }
    # D, [' K) w1 \% K9 g
  1012. }
    & [6 U& G, `6 J! c3 e5 v

  1013. " c) w( U/ w  @5 A# \3 z
  1014. /************************************************************************/
    5 Y) S/ G) p4 S7 g0 b* _
  1015. /* PROCEDURE: Verify                                                                                                        */  l5 k( {5 ]% L2 X- ?" ?
  1016. /*                                                                                                                                                */
    5 k! |! o" @, [2 \/ T
  1017. /* This procedure checks to see if the correct byte has be read.                */$ s' E& }4 t8 a5 M. [" W
  1018. /*                                                                                                                                                */
    3 R! @2 J$ @: l3 y% F$ \
  1019. /* Input:                                                                                                                                */
    ( i: \: X5 Z+ [. D: O, H
  1020. /*                byte:                byte read                                                                                        */
    5 p% y' }! Y  @4 l2 n
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    ' d) u- V* w# W) }
  1022. /*                                                                                                                                                */
    3 e3 \! l; \! C
  1023. /* Returns:                                                                                                                                */- @4 v( G) i2 Z  a3 t! N
  1024. /*                Nothing                                                                                                                        */0 c* n3 r! b/ Q6 h& a" e
  1025. /************************************************************************/
    ( E0 |5 }9 N  _* E2 v: @
  1026. void Verify(unsigned char byte, unsigned char cor_byte)+ ^; ]$ J* {5 o* M( u4 V3 X8 m
  1027. {
    & w* ]  d) T/ ~3 L7 L6 k0 j& v: ]
  1028.         if (byte != cor_byte)
    $ D+ n& v+ f% F5 F
  1029.         {# {* k6 M- J; o8 D
  1030.                 while(1)* R9 Z5 J8 w) o1 q- z
  1031.                         /* add source code or statement for this file */
    ) G* t$ z/ \" s5 p
  1032.                         /* to compile                                  */
    5 T2 ]4 c: o) ^: T! w2 T1 [
  1033.                         /* i.e. option: insert a display to view error on LED? */7 H. w0 ]7 y- R3 b( F) s5 m
  1034.                
    3 P# g% y0 q. F# W4 L
  1035.         }
    0 i7 n/ |; a% z5 D2 P
  1036. }
    % d: g3 Y# u& f& u# s: X. L

  1037. ( ~& Q3 x* H1 X# H7 u
  1038. # ~$ u4 g/ P: {% R; d
  1039. int main()5 J" K1 D( l# r% g2 L* p9 C0 E9 J
  1040. {
    / G8 z1 y8 @, ?% ]3 ^% K% p

  1041. 7 l. V9 ~+ N* a0 W: Q5 U# O6 C
  1042. return 0;
    3 U2 g4 F0 p( s+ S- Y# a; H' X
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:2 X8 O. Z" X& G5 e
   main()2 e% R- J9 U7 v4 x
   里面怎么是空的呢?
& v) d$ q' d- V: t7 |# u) `# \1 C   发一份给我吧
" Z7 v0 q) F+ r8 @; \! Pmail:luyijun2005@hotmail.com
1 k: q% d0 k& }8 V+ b咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。# R; R1 U, X1 b

8 C* Z2 @9 R0 c8 M[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。: _( _% C* d1 D$ x6 i& `7 d
EC的代码在哪跑,你看DS的说明,每个EC都不同的。
" S- B- H, g6 z- KOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?5 G$ e& T. E: z
上面几个问题是你没看任何东西而白问。
8 ~% t% w+ g! p+ J8 }. _6 r$ ~6 j
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。+ F7 L; g5 v  e7 \; Z/ {! O' a
- l, v$ w- D/ J5 q6 }; h. ^
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
, U$ [4 y' g2 v2 P5 T: ~- ?$ T  l" R+ D0 s' k/ o
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
9 p6 O/ \# Z8 B, n: n" }0 z: g* s1 {) \. K
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...# ^& Q4 Z! f. q; A. w
7 L4 Q& K: e- g: r: |- [
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
" C# i3 ?( X4 j6 x! v' H似乎要把SPI能support 到最大,这EC chip应该有好卖点
6 c: F$ X  ]; F! R" ?6 e) sBIOS功能要不要强大,也就决定了SPI Flach的大小: x( Z) K8 d! j( o3 C; |. O
我是这么想的~让OEM去决定要挂多大!" u0 E. Z' |# Q4 |# j- ~! i+ Y- }
如果我司有BIOS工程师就好了~哈
8 \# G+ F9 p/ a$ [( \! _1 B8 [2 ZWPCE775应该算很新的东西,来看它支持到多大?
) a( z8 k) S% F5 N+ \& e$ q# [- I" S' S
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
8 u( Q" `/ g5 l, d, F- c其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.1 w2 O' p2 O7 ]3 R  I
! q# D; A/ o; Y5 {* P+ M
这份driver收下~希望以后有用到
( `2 T: o4 y/ t( q1 s, X谢谢bini大大
7 i1 G+ h( b9 c0 ?( _# A$ z
8 H: O; m! F5 F. i2 p很新很新的新手,如有错误请指正 (准备看第二家的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()
1 ~' N  I/ U$ \  M- z6 k  b; E, A{3 C/ e+ M+ W  R$ ]- S% d
        unsigned char temp = 0;$ x$ }# V7 l: K4 v7 h& Q
        CE_Low();5 O0 {; J/ y$ K0 z* j) c6 D
    while (temp == 0x00)        /* waste time until not busy */
0 X6 N" {. s& l0 L6 C  Z, X                temp = SO;
5 [4 s# [3 M( P3 g8 R  y4 c% E9 z! Z        CE_High();
0 A1 f' w& u5 N+ b0 f. O}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)/ F' G' f/ s, {/ @# X$ X
{
% L) w+ F- I" d        
' L8 `, l: w  b5 ]5 S6 d        unsigned char i = 0;
% @" |  K! N8 D3 Q9 ^2 H+ D7 G( q" ^        for (i = 0; i < 8; i++)+ B" P: O6 A8 w4 b
        {) q7 @* \# G9 w% Z" ]( q2 _
                9 N9 ?( x& z( F* h- r
                if ((out & 0x80) == 0x80)        /* check if MSB is high */
" f. K; r# j) \) g0 Q                        SI = 1;
' u+ s/ I/ L9 |# c6 N8 I3 P' F                else
1 u+ ~8 k$ x' Y3 b5 C& e+ w                        SI = 0;                                /* if not, set to low */' {& H) a9 G! k3 j
问              SCK = 1;                                /* toggle clock high */
& ~+ n1 i0 j5 B0 A. X   题            out = (out << 1);                /* shift 1 place for next bit */: p) {; P' n( R/ A
                SCK = 0;                                /* toggle clock low */) a  W4 z+ R; i, G) o
        }0 z/ l5 h) _6 L; F9 r2 p
}; g9 r( M# I" j9 N2 F! Y2 ]
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-6-29 02:44 , Processed in 0.228844 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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