找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55267|回复: 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. R1 k" m  b0 e  i* w4 q! t- u

  2. 1 _: C* v6 x2 k7 |  ~
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    : E9 \+ _! X# F' [# K/ e/ |
  4. % L( f& J, ?" W, N. W, m  T9 ]
  5. November 4th, 2005, Rev. 1.02 p5 e5 D! M7 H; w3 N/ t$ Q
  6. 3 Y* n- p4 l0 ?0 d3 m6 g
  7. ABOUT THE SOFTWARE* j/ m' A6 M; S$ m
  8. This application note provides software driver examples for SST25VF080B,
    2 m8 e7 u# ?2 ], A: L3 J0 P
  9. Serial Flash. Extensive comments are included in each routine to describe
      x0 F8 C3 B' E9 i& ~
  10. the function of each routine.  The interface coding uses polling method
    ; [2 s- N1 Z; a* c+ Y
  11. rather than the SPI protocol to interface with these serial devices.  The! m: ?: L" i. A( N/ j0 Y8 Y+ }
  12. functions are differentiated below in terms of the communication protocols
    , m8 j" f2 N( {# k* d" m
  13. (uses Mode 0) and specific device operation instructions. This code has been 5 x! j% `: J# N
  14. designed to compile using the Keil compiler.
    6 O! j; c. i- V; S! j- K1 E3 p/ f( W5 X/ I

  15. " I4 K3 e0 _, s, _* |5 ^5 m

  16. 8 z. i* L! @6 y2 C+ _
  17. ABOUT THE SST25VF080B" [  X/ H4 _' a9 t2 Y; \

  18. 3 C1 ~& ^* Z  R$ h% u) K
  19. Companion product datasheets for the SST25VF080B should be reviewed in # ^) [! W8 n9 K# S0 `9 c
  20. conjunction with this application note for a complete understanding 6 L( B* F2 K( t9 H
  21. of the device./ S. Q) M4 m' f7 U5 d& s; p# Y1 U
  22. ' D, h0 e3 ~. `  t3 Y

  23. 2 \9 v$ c6 F0 {* ~: i
  24. Device Communication Protocol(pinout related) functions:
    4 J7 K' \) r! Q6 E/ f$ R

  25. ( m; E9 z# f2 n$ ]  r4 e: B: \
  26. Functions                                    Function
    / E* m# I4 P( g" E6 K
  27. ------------------------------------------------------------------
    ' `. u& X& Q! L  E
  28. init                                        Initializes clock to set up mode 0.
    1 }/ @1 e; b  d7 M9 U
  29. Send_Byte                                Sends one byte using SI pin to send and
    / e% r, A: P. C, G: `! e
  30.                                                 shift out 1-bit per clock rising edge
    $ H8 V; Y8 ]4 r) e8 b! C8 [
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    7 g) a* c& T" |: ~
  32.                                                 in 1-bit per clock falling edge
    9 A; r8 q- C% o0 b, Z; R: U
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    3 T+ G- J1 F- x, C1 V: H
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    : W8 D6 h- B% F( O3 @# z9 U! _- o
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    & l: x8 R; P# p9 j+ ?
  36. Hold_Low                                Clears Hold pin to make serial flash hold5 T& E/ F6 `+ s
  37. Unhold                                        Unholds the serial flash5 t) Q7 r% R; V. ~* ?
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    & I$ ]) {9 ~' g' B
  39. UnWP                                        Disables write protection pin
    , O5 d: r8 a; g) X: q/ P
  40. ; I$ B4 c; F, n7 ?1 ]- F# Y
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code% r- F  m) K) }' D' W, Z2 f  C
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your9 M+ L3 h6 f8 y1 ^3 o& V
  43. software which should reflect your hardware interfaced.          
    2 k% G! s. x/ d4 j

  44. ! l% k( ?5 `* F$ U2 y  H. R
  45. ( D3 m9 q" g( }! V9 A7 `
  46. Device Operation Instruction functions:
    , @. e# q# e7 m) f

  47. " h8 l9 r0 e2 v4 l6 S
  48. Functions                                    Function0 ~+ L1 q$ V1 g$ p/ Y# |
  49. ------------------------------------------------------------------8 L+ j/ @' y; r
  50. Read_Status_Register        Reads the status register of the serial flash
    , v3 @) `& O  o2 j3 v
  51. EWSR                                        Enables the Write Status Register
    % i( P1 s4 c0 p- ~
  52. WRSR                                        Performs a write to the status register
    2 n* @% @+ Y8 j3 i: \9 _- ?
  53. WREN                                        Write enables the serial flash
    3 i1 g2 d4 t: O& l. E/ a
  54. WRDI                                        Write disables the serial flash
    1 Z. ^8 L8 x* W2 [5 P
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    * e+ A; B" G# W  U$ d
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming$ s0 d- h% ^  M0 I
  57. Read_ID                                        Reads the manufacturer ID and device ID
    ' c4 n$ ?3 `; O- E5 h. a" K
  58. Jedec_ID_Read                        Reads the Jedec ID2 r. j( c9 h1 H/ m- a
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)4 p* W- u. s/ k) B
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency), F6 ]3 K# p3 V) |6 g! s; }
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)' a! k0 S( c) n; o
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency): B) T3 D$ D0 p: L7 }
  63. Byte_Program                        Program one byte to the serial flash7 T, i# {4 ^* Q) c
  64. Auto_Add_IncA                        Initial Auto Address Increment process" [! x+ |7 {0 L) t5 i# }
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation: E, f# a+ O6 S6 M4 h  Y
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    ) O4 j$ ~7 |+ h
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
      y: t4 O: p' B, T9 a' K
  68. Chip_Erase                                Erases entire serial flash
    ( m  u3 T! Z$ f: o8 a9 p$ ~
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    . r, W  }. N4 [0 g7 F
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash% o1 Q6 Z, e$ H% m. q* N
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash, k& ^# h: \+ k; l9 G# o
  72. Wait_Busy                                Polls status register until busy bit is low
    6 p8 ]2 i$ p8 {- @1 c$ M. |
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming8 o+ j" B9 n; u) |: D
  74. WREN_Check                                Checks to see if WEL is set4 p+ m0 S3 g- O6 w
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set; x% Z- o6 ~. n) l

  76. 4 z% r! t  C1 Q' g& m5 Q& K

  77. ! j; w8 [) }- ]& S( G7 |5 e
  78. ! u, H* ~( \; Q3 v: i
  79.                                                                      
    8 U- p3 b3 p9 V- K, T" _! \* q
  80. "C" LANGUAGE DRIVERS   D( t1 C1 N- ^' p+ I
  81. 8 ^" h! J/ C7 `+ o( G
  82. /********************************************************************/. v# c0 m. J5 K# C* j1 u  |) l, {
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */: |. l  e  h. t/ N! n+ }4 s( h3 }
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */. h) g' G( l# a5 h2 u& V0 N
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */) E0 ]" ]- v1 i- b2 Y, C/ j. l, o
  86. /*                                                                  */$ N0 C( }+ n* q  ?+ M4 z% E( J
  87. /* Revision 1.0, November 4th, 2005                                                                          */   7 R1 x* M! c/ H9 N3 H! k9 M
  88. /*                                                                  */: L+ x( k( W0 p( T
  89. /*                                                                                                                                        */: N7 q6 M. n( {7 m2 k' @
  90. /********************************************************************/
    $ U5 ~3 r9 Q" @; v. o. t. Y' U

  91. % |- |: U+ @' B: G' `
  92. #include <stdio.h>/ U7 y2 S- w4 _
  93. #include <stdlib.h>
    # @6 u( x( i5 a3 m

  94. ( |, i$ `9 ~/ j0 I
  95. /* Function Prototypes */* V" K' s- ?# }/ g+ n0 B

  96. 8 Q, G) ]' `5 i  B5 J) I
  97. void init();/ e. a2 N( W; ]# Y7 M
  98. void Send_Byte(unsigned char out);
    " [! Q  J7 @# g2 P+ I
  99. unsigned char Get_Byte();
    1 O/ }) g* a- S& H, r$ e: f6 J& L
  100. void Poll_SO();
    2 P& I) P# G0 r
  101. void CE_High();9 {7 |+ V. f3 N
  102. void CE_Low();
    ! j( a6 F6 Z  r9 X6 B0 M
  103. void Hold_Low();- t1 H: B, Z! Y! _* k" C( h
  104. void Unhold();# x* [2 a# h$ x4 \
  105. void WP_Low();4 G! H, g0 ?( H" c5 Q
  106. void UnWP();; e2 C7 N; L5 m' v8 G0 R7 s
  107. unsigned char Read_Status_Register();
    4 \! C+ t/ Y0 b7 y7 l1 v9 ^
  108. void EWSR();8 X6 J1 a' K# M+ c, [2 L9 ]8 s$ \
  109. void WRSR(byte);
    # F! n) s/ V& e" `
  110. void WREN();
    4 P, }: L. x% p" v* Y1 l. N9 U
  111. void WRDI();9 R' v4 z7 z2 e& O
  112. void EBSY();
    : |9 `  t. d3 u% u4 v. H
  113. void DBSY();' a" k2 ^. [% w% S. n  d
  114. unsigned char Read_ID(ID_addr);2 i7 M! X' m" C
  115. unsigned long Jedec_ID_Read(); / C: E9 c! t7 }4 X
  116. unsigned char Read(unsigned long Dst);
    * U9 ?3 m9 L1 q* g- S
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    # T3 N% Q+ p. |- R+ _* @% l
  118. unsigned char HighSpeed_Read(unsigned long Dst); 5 {& T) _: R" x" u
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);2 Z: r5 A) R" |: E2 Q" g6 {
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    3 g5 {4 G$ k, T1 n) Z
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    7 g/ a2 b  q4 O( S; F2 r5 R/ I
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    3 t/ w- M  ?! F9 `7 d
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    4 S6 X, T1 r4 |% T
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);5 y6 W/ A( _; ~; {7 t
  125. void Chip_Erase();) A) o% E  q3 L/ Y  J
  126. void Sector_Erase(unsigned long Dst);; ^3 O! g$ f) N) [
  127. void Block_Erase_32K(unsigned long Dst);# s3 c( C$ `' ~- l  F
  128. void Block_Erase_64K(unsigned long Dst);
    ' X" s, y% l. N( i% t: b
  129. void Wait_Busy();* E4 a9 F4 r; Y& N4 }0 E: K
  130. void Wait_Busy_AAI();9 v. ~$ j: {& J) r: \
  131. void WREN_Check();
    8 n. ?0 ~% N7 N1 k' s
  132. void WREN_AAI_Check();
    ( Q5 u- [2 q' C$ U! ]
  133. & n; H' f$ v7 F2 I! P( |$ C4 u* o
  134. void Verify(unsigned char byte, unsigned char cor_byte);/ O2 x! N, ~/ O* d7 ]5 r  l/ `& |$ Q
  135. ) ]" J4 ?1 l! X) H, [
  136. unsigned char idata upper_128[128];                /* global array to store read data */% M$ b) H; o5 Z' C, j  N; L% I( I
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    : \7 n1 K/ z/ r" ]( g0 ]& \' q1 \

  138. 0 V- X/ y9 ^0 ^5 [' z: U$ r
  139. /************************************************************************/  y8 R4 e: F5 h
  140. /* PROCEDURE: init                                                                                                                */& N$ A# k- ]$ ~: c3 F
  141. /*                                                                                                                                                */* ]  T# \. ]9 E, C4 Q/ X2 F( B
  142. /* This procedure initializes the SCK to low. Must be called prior to         */' ?: |+ h. Z$ F
  143. /* setting up mode 0.                                                                                                        */
    3 ^# G4 o& y6 O& M1 A* q: ]5 K  a
  144. /*                                                                                                                                                */
      I& ~  U$ p3 n/ L4 T7 Z( M
  145. /* Input:                                                                                                                                */
    $ j* r  q: f' d) L% u7 j$ m- f/ F
  146. /*                None                                                                                                                        */
    ' P1 w! w  q  u9 @: d4 L
  147. /*                                                                                                                                                */
    & H* _& T+ W' I7 W/ O" j7 r
  148. /* Output:                                                                                                                                */  i) \& Q0 o0 o8 k' W& u/ X
  149. /*                SCK                                                                                                                                */
      D' r* l0 b: V( }
  150. /************************************************************************/- t0 i: J5 O; ^, @' q
  151. void init()
    # j$ l8 D8 Q" _! `) b5 G% x
  152. {, f6 ?: o1 p9 o9 \
  153.         SCK = 0;        /* set clock to low initial state */
    - c; _$ I1 w" F; H' [4 w! \
  154. }. X, d* A( t9 }1 m7 f

  155. 3 J" Z+ L+ C. W. ]) o3 h( E4 T
  156. /************************************************************************/
    & ~! [; b& n. m0 S% H* _
  157. /* PROCEDURE: Send_Byte                                                                                                        */; \, u6 N  U1 X- m8 @1 ?
  158. /*                                                                                                                                                *// u# }2 i! y; Q  `) E
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */6 r" a# I' R+ q! X0 j6 ?- i
  160. /* edge on the the SI pin(LSB 1st).                                                                                */& C' q/ r( V/ X1 D! {
  161. /*                                                                                                                                                */  E) h( r/ u  S  v2 w7 m  J+ V
  162. /* Input:                                                                                                                                *// f( o+ ^: u+ j' T2 I# Y1 J! o
  163. /*                out                                                                                                                                */
    1 `- M6 K; u7 p# @# b/ E5 D
  164. /*                                                                                                                                                */
    ' }7 \& S) J- x1 C( H
  165. /* Output:                                                                                                                                */
    : Y3 a% d* o- \0 H8 ?% b3 f
  166. /*                SI                                                                                                                                */
    ; j3 ]7 h( Q$ B8 D8 Y! e* m% U
  167. /************************************************************************/
    % ?  D$ w! E- p- r0 c
  168. void Send_Byte(unsigned char out)
    ; z" g$ V$ h" q* J* {% X. Y
  169. {
    ! \; I5 y0 Q9 Z: t  t
  170.           U9 }& X9 B0 k4 t, x3 _
  171.         unsigned char i = 0;
    ( |  L9 j% L0 @4 L% i
  172.         for (i = 0; i < 8; i++)
    $ m+ k1 d3 N8 `8 J# L  [7 F1 V
  173.         {
    0 A) G: G. L2 U7 c% K4 e! d6 f
  174.                
    ( {0 {" L& ?* E- [" g
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */' ]& ?( j3 {; {- r
  176.                         SI = 1;% a; {8 h/ {! i; j2 S* y& m
  177.                 else* U0 W! L3 U9 ^
  178.                         SI = 0;                                /* if not, set to low */
    3 j7 N4 \% P. G6 s
  179.                 SCK = 1;                                /* toggle clock high */) w9 C, r. N5 I! X+ T  j
  180.                 out = (out << 1);                /* shift 1 place for next bit */! d! X% k% }8 n+ J; Y2 z
  181.                 SCK = 0;                                /* toggle clock low */
    ( X2 D" f6 v+ B6 `7 O
  182.         }
    * O% y6 v& X+ v* t% R8 o1 x! B
  183. }' b* `5 T$ i. w) u( c

  184. . Y# _. }  T7 }- P. R
  185. /************************************************************************/2 X4 g% j& f. |6 L* u6 S0 h) _
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    + V; h8 m0 z5 e; Q8 G
  187. /*                                                                                                                                                */
    ( r1 `- U+ [: l5 L2 y, o0 W
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */3 F+ e1 S: k4 `( U3 L- s
  189. /* edge on the SO pin(LSB 1st).                                                                                        */& W: V  Q( C% G& {8 B8 n) P
  190. /*                                                                                                                                                */8 s9 T1 ~* b: g
  191. /* Input:                                                                                                                                */
    3 n' z3 a2 E* r4 a! j
  192. /*                SO                                                                                                                                */9 A& K- M) l  P! G
  193. /*                                                                                                                                                */  N2 ]" y8 b! M; w0 Y; f" M, n7 s
  194. /* Output:                                                                                                                                */
    ; ^# J% I8 P9 M2 y. V
  195. /*                None                                                                                                                        */
    " T. ]+ B4 K8 t5 s
  196. /************************************************************************/
    0 F/ n( U' s. o$ H
  197. unsigned char Get_Byte()9 S7 z' B3 x+ g) v
  198. {
    8 s& V1 R9 P* r# R$ t
  199.         unsigned char i = 0, in = 0, temp = 0;7 w  k: M* a6 s& v
  200.         for (i = 0; i < 8; i++)
    " a8 o7 `- c5 h6 W0 `
  201.         {! V; p* E1 F" B
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    6 g% X% F/ Q$ g8 S
  203.                 temp = SO;                        /* save input */- j8 q4 U: g7 C1 C% l. T
  204.                 SCK = 1;                        /* toggle clock high */9 K) T) Y. u8 M3 u" L+ ~
  205.                 if (temp == 1)                        /* check to see if bit is high */- k0 `5 D% j/ y% a
  206.                         in = in | 0x01;                /* if high, make bit high */
    2 V0 P" c# {$ O% U" Y

  207. ' H. R- Q6 h% y# ^6 W
  208.                 SCK = 0;                        /* toggle clock low */4 O$ R% }8 }& N3 M- W8 L- F
  209. ( y$ I4 G" {# T7 i$ F& r. L; ~1 m
  210.         }6 Z: D0 v2 j: U: @( u4 d9 e
  211.         return in;2 z9 b) z- f5 X) ~& T
  212. }! Z4 a9 X+ `: W" y% m& |2 }- X; j
  213. 1 f# Z$ E; G6 u# y, g& ]
  214. /************************************************************************/& ~* H1 s4 m# P; _
  215. /* PROCEDURE: Poll_SO                                                                                                        */3 z4 o* K( a' {2 ~' x
  216. /*                                                                                                                                                */
    8 X/ t# H% e4 D2 J
  217. /* This procedure polls for the SO line during AAI programming                  */
    3 R+ N+ ^+ J, o6 R4 J3 S3 n
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    1 s! }* g( P' M) X. z
  219. /* is completed                                                                                                                        */* Z8 n% H& ?( `
  220. /*                                                                                                                                                */0 t. G/ z7 K5 i# x4 y  T
  221. /* Input:                                                                                                                                */
    7 I+ s- }6 ]' Z9 O1 P, J& e6 v
  222. /*                SO                                                                                                                                */6 {) y2 {- |: u* p7 R- }, v
  223. /*                                                                                                                                                */2 S+ L7 Y8 c+ Z- D
  224. /* Output:                                                                                                                                */
    2 C" e- [9 B6 Z, U
  225. /*                None                                                                                                                        */
    + e3 \$ Z4 c7 L2 V
  226. /************************************************************************/! [4 `2 R7 I4 g
  227. void Poll_SO(); N7 z2 O% j6 f# _& l+ s: y
  228. {% s# N' c: b$ f0 h9 Q, T
  229.         unsigned char temp = 0;
    6 i: L  h! y0 m* L6 y* N
  230.         CE_Low();
    ) H7 C1 [) u  X6 }+ K( K
  231.     while (temp == 0x00)        /* waste time until not busy */
    : {' |1 e- X0 w! P  E
  232.                 temp = SO;% l' g! N* g$ |6 r
  233.         CE_High();, o9 p. H1 ]2 r" y1 X) m$ z
  234. }* h8 F- B- j/ E1 u. G" ^
  235. : l6 v, Q7 Y- d- Q4 P( Z" p
  236. /************************************************************************/
    ) N) j  a$ @# h) l9 D0 |; r
  237. /* PROCEDURE: CE_High                                                                                                        */# L0 B7 T1 n  D3 I5 ^- u
  238. /*                                                                                                                                                */
    # b  }) ]+ a4 V9 `' j: J
  239. /* This procedure set CE = High.                                                                                */6 D& H+ P1 G6 K
  240. /*                                                                                                                                                */* w* @1 J& v$ y7 Q/ l0 k7 Y
  241. /* Input:                                                                                                                                */
    # ]9 o  @9 _. m# s5 q
  242. /*                None                                                                                                                        */
    ( {) }' Y0 _# N- X( O
  243. /*                                                                                                                                                */* }. ]9 x' {+ o$ T! S2 h1 U. D- o0 M6 p
  244. /* Output:                                                                                                                                */
    ( u6 G" v/ f: c, H% }; \6 e
  245. /*                CE                                                                                                                                */
      ?4 o3 P9 c, T
  246. /*                                                                                                                                                */
    , \9 w; V% U( o, {; d4 D
  247. /************************************************************************/
    & r& Y0 T1 i% K; K8 F7 w. `+ s
  248. void CE_High()
    * r  ?% D' M1 a3 U  Q1 I% z: ~
  249. {6 F; L0 J% \# E2 V1 |
  250.         CE = 1;                                /* set CE high */
    3 S( X2 m  e+ j9 {9 c5 V
  251. }
    & D' _$ p( F& p' Y- [  G" M) ^5 B
  252. 5 @: b- M  S+ [/ q1 w0 l2 U7 t
  253. /************************************************************************/0 m! t& l" Y" w* g3 [* B
  254. /* PROCEDURE: CE_Low                                                                                                        */, m6 ?; P" O' z- T7 r9 \6 d. w
  255. /*                                                                                                                                                */
    8 y" b/ t& d  P
  256. /* This procedure drives the CE of the device to low.                                          */- L+ z2 u1 a; _8 Q9 [4 _0 h
  257. /*                                                                                                                                                */, i$ T; l% l" S6 \0 s
  258. /* Input:                                                                                                                                */* _6 V+ X) e6 z
  259. /*                None                                                                                                                        */* z0 T( J  e! a0 V
  260. /*                                                                                                                                                */
    3 C3 p* Q( q2 t5 V. b: \) ]+ v
  261. /* Output:                                                                                                                                */
    2 {6 T, c8 o* H
  262. /*                CE                                                                                                                                */
    9 H# P7 c' X$ \* w7 f
  263. /*                                                                                                                                                */
    $ f& }0 }3 ^9 d4 u  r$ Q
  264. /************************************************************************/; D" O$ W+ r$ P$ Y( x! s  M- B
  265. void CE_Low() ( d2 [( N1 n/ ]5 D
  266. {       
    8 b4 R: e; B) I4 }- ?9 t# z
  267.         CE = 0;                                /* clear CE low */
      ^2 g& G, N( X2 X2 \
  268. }
    & [% \- |$ ^) E% i

  269. 9 e5 C; l+ N" w# Z2 R1 o
  270. /************************************************************************/$ V* q7 V. @4 S" b
  271. /* PROCEDURE: Hold()                                                                                                        */
    ' T# x+ F6 W# J7 U: W& i
  272. /*                                                                                                                                                */
    7 T& j' ^* a& b$ z7 f
  273. /* This procedure clears the Hold pin to low.                                                        */
    4 {* X: A' R8 ]: Y! Z* t; r
  274. /*                                                                                                                                                */
    + P' h- ^) j% a6 e
  275. /* Input:                                                                                                                                *// D7 @. \8 f2 f$ L8 N
  276. /*                None                                                                                                                        */+ o8 f: V' k" u4 m# e6 X; z
  277. /*                                                                                                                                                */
    ; x3 F6 b6 P$ w4 C0 B' \2 O" D; m
  278. /* Output:                                                                                                                                */
    ) {9 i8 G; F( U" W
  279. /*                Hold                                                                                                                        */
    + s. f1 a7 @* ^: X. V8 v
  280. /************************************************************************/- f/ c; ~8 b; m+ s" Q' s8 K
  281. void Hold_Low()
    ' V1 h, v2 `6 @
  282. {
    7 R: ~  q7 U" N6 a- e- k
  283.         Hold = 0;                        /* clear Hold pin */8 h( H1 B/ N/ |9 ~" C- B
  284. }
    : U9 u1 \$ L2 g
  285. 0 }* i9 T+ q) p4 P9 s7 `7 h. A' k5 ?
  286. /************************************************************************/9 K, b3 s$ T! O+ j6 q: o
  287. /* PROCEDURE: Unhold()                                                                                                        */( s& L/ d, B- z, G- h8 o6 W- ]
  288. /*                                                                                                                                                */& V: o; D  h, r) k6 G# X0 F$ X* Q( B
  289. /* This procedure sets the Hold pin to high.                                                        */% s; F' M2 c7 ~8 I
  290. /*                                                                                                                                                */5 r5 I9 _9 v5 |7 A+ o5 U$ E
  291. /* Input:                                                                                                                                *// b# D; D0 N9 b5 a
  292. /*                None                                                                                                                        */
    9 f9 s/ J3 h( J& b0 G, v/ n
  293. /*                                                                                                                                                */
    3 M( R8 D. Y" w
  294. /* Output:                                                                                                                                */
    " Y; w  A+ Q+ t, v. ]
  295. /*                Hold                                                                                                                        */$ ]3 @/ {7 S% A8 @7 f
  296. /************************************************************************/
    & i, c* v5 H  J) ~. e- z
  297. void Unhold()1 @/ b, J" A( X( Z" F) @  ^" w
  298. {
    2 w! c; ~5 u- i5 Y* j9 j
  299.         Hold = 1;                        /* set Hold pin */
    ) A' J7 z, S" W5 j' w& j' k
  300. }) i1 U/ ]8 B1 d; i  W

  301. : n+ s& Q! U/ X: m3 V! D" u
  302. /************************************************************************/0 a! y- k; v9 z6 h
  303. /* PROCEDURE: WP()                                                                                                                */8 I: t2 S% @5 k
  304. /*                                                                                                                                                */
    - h. |; C4 K5 t' N$ w7 A
  305. /* This procedure clears the WP pin to low.                                                                */* X: X1 D7 d( m6 ~3 f  y
  306. /*                                                                                                                                                */
    ; J) R1 M: ~# e  G- t  |
  307. /* Input:                                                                                                                                */' |' W- O$ \' q+ c2 N. [
  308. /*                None                                                                                                                        */% K4 ]( Z6 Q& [/ Q
  309. /*                                                                                                                                                */
    3 Q5 E+ Y) Z' L. G  j7 m' |( [
  310. /* Output:                                                                                                                                */' H5 p  ?3 D" ~- g( |+ G
  311. /*                WP                                                                                                                                */$ y9 ~( |# |- J6 v* F$ z6 B
  312. /************************************************************************/* _+ U8 z6 d0 A
  313. void WP_Low()
    & T% O* m9 ~0 j& a3 c+ T0 E
  314. {
    2 b6 x- ?  t  \7 r
  315.         WP = 0;                                /* clear WP pin */+ z) Q% t8 G9 D  k  A9 o0 v& ]
  316. }
    2 N& G" S+ R) p; k- Z- ?

  317. 8 O- S, E% X6 s0 ^1 ]( X
  318. /************************************************************************/
    # D/ U/ Z( A* u) {  x- q( |( r
  319. /* PROCEDURE: UnWP()                                                                                                        */
      ?- g2 X$ D: }1 _  M
  320. /*                                                                                                                                                */  x' l$ D$ u, N. q6 H! `; T
  321. /* This procedure sets the WP pin to high.                                                                */; Y4 n. z" _) ~9 K3 N
  322. /*                                                                                                                                                */
    3 u( g3 \8 F  V1 G
  323. /* Input:                                                                                                                                */
      {- s8 y1 o8 g; S' u0 p
  324. /*                None                                                                                                                        */
    1 V1 E% U' v, H' b
  325. /*                                                                                                                                                */5 A, X: M( {3 e) J
  326. /* Output:                                                                                                                                */0 t7 ]2 }  d- }
  327. /*                WP                                                                                                                                */
    " X2 z- o; O/ |- _0 e2 S! R6 I  Z
  328. /************************************************************************/
    5 M3 h6 Z: v2 h. b, V0 |! G
  329. void UnWP()" [* G& m. }' b3 ~
  330. {, ?+ n$ h  _! Z$ m5 |
  331.         WP = 1;                                /* set WP pin */
      Q6 b" z, y8 `/ s
  332. }
    8 \' e  }& r5 I" A! c* ^0 g
  333. " x; M. l) d5 M' o  T
  334. /************************************************************************/5 k2 q8 `2 Y8 ?6 o7 F
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    " k! H( I7 F# k5 p$ v6 t
  336. /*                                                                                                                                                */
    7 j* Y4 q' t$ x' w7 A
  337. /* This procedure read the status register and returns the byte.                */0 V  D. K" A" t, P4 ?9 V( \% ?3 U
  338. /*                                                                                                                                                */
    - I0 L) R6 `! W4 N, d  Q
  339. /* Input:                                                                                                                                */' S% ~' w8 R, N0 k, P, K% d8 F
  340. /*                None                                                                                                                        */
    6 x# c8 r0 c, ^" |1 d' `  F
  341. /*                                                                                                                                                */* d( A- N- o. U: X. C" n' j/ f0 j
  342. /* Returns:                                                                                                                                */, E4 O# ^& t, K
  343. /*                byte                                                                                                                        */1 z0 O' T2 @/ ?: C6 y! i
  344. /************************************************************************/
    0 C$ z7 t2 c9 [$ O* T! F
  345. unsigned char Read_Status_Register(). P4 |) v4 D" N
  346. {  U: r. n; N6 A) Y* }9 i+ J
  347.         unsigned char byte = 0;
    . w+ Z. f5 f% j  M+ {' k
  348.         CE_Low();                                /* enable device */
    2 s; x8 b( E5 }' v* K& ]
  349.         Send_Byte(0x05);                /* send RDSR command */) [( r" |1 h3 r
  350.         byte = Get_Byte();                /* receive byte */' u! m7 E8 X& y
  351.         CE_High();                                /* disable device */6 R/ \' a, p: v5 y0 A
  352.         return byte;
    2 N/ B) b& \- r# a* K; l0 w
  353. }
    ; r3 }1 `1 D# z
  354. 0 i7 X+ u$ Z$ U+ G0 S) B+ n3 O
  355. /************************************************************************/
    2 ]3 W: U! m+ D) C1 a- A
  356. /* PROCEDURE: EWSR                                                                                                                */
    # D: m) X  q. O' `  k0 S0 c
  357. /*                                                                                                                                                */
    1 }" F; H; j( p5 g! t1 A
  358. /* This procedure Enables Write Status Register.                                                  */
    4 q- a( o7 V4 w; c& ?; j9 Y
  359. /*                                                                                                                                                */
    9 ^6 c; f0 v" J6 H4 u
  360. /* Input:                                                                                                                                */
    * u9 h5 @2 @( J3 Q2 b5 k* c  o
  361. /*                None                                                                                                                        */
    0 z/ Q- r& E9 R2 S/ S: S
  362. /*                                                                                                                                                */
    6 J, i) R! R% o6 |, e
  363. /* Returns:                                                                                                                                */: G* d! |& O4 `; |" L0 y) ?8 P
  364. /*                Nothing                                                                                                                        */: }# b5 x/ }2 R
  365. /************************************************************************/
    : k0 [- r8 V5 k, t( g$ ~! X
  366. void EWSR()
    - V7 l. v/ F' l8 {1 d( [3 ^  D* p+ q& p
  367. {' A6 E: j3 t6 T* y3 p6 S6 u3 V
  368.         CE_Low();                                /* enable device */
    0 i+ K6 _% Q& M+ K* q& C
  369.         Send_Byte(0x50);                /* enable writing to the status register */- X% a3 O( O- H: H9 V: l. F
  370.         CE_High();                                /* disable device */8 v  @5 y. a0 a4 l; H- s8 O  t3 E
  371. }; f5 B0 E8 g* P2 l/ U. w

  372. , b! `1 {0 O6 `
  373. /************************************************************************/
    9 d7 B9 c6 Z1 X5 i4 }- s" l% C. I
  374. /* PROCEDURE: WRSR                                                                                                                *// W- n8 U# }* F5 `: P# j3 X: \
  375. /*                                                                                                                                                */
    6 a3 R/ k# i) A" ~
  376. /* This procedure writes a byte to the Status Register.                                        */; ^# k1 q8 y; e+ i) r: ^) L4 K5 U, Z
  377. /*                                                                                                                                                */! T7 G4 u+ B  S' t2 l8 N
  378. /* Input:                                                                                                                                */. p& X6 W; C6 Y* N, X+ Y/ q& r
  379. /*                byte                                                                                                                        */  g- D' s9 c. y1 J3 D
  380. /*                                                                                                                                                */; V1 d5 A" J) x% R$ i0 T  L% D
  381. /* Returns:                                                                                                                                */
    4 K5 ]' r- O' Z. l$ O! }6 z3 b6 N
  382. /*                Nothing                                                                                                                        */; k: }  O/ d9 D9 |, n, P
  383. /************************************************************************/
    % ^# M7 c* L" v* c- b6 S
  384. void WRSR(byte)
    ! G4 N/ `+ A  E1 ^6 Q1 Y+ H
  385. {) o( G, w* e3 \( X9 B% Z# K
  386.         CE_Low();                                /* enable device */
      w5 w& ~9 z" B
  387.         Send_Byte(0x01);                /* select write to status register */3 T9 H7 t# K8 ?- W, O- T
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    # f8 O  D! V) l! H5 r9 L
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    : K2 }: b/ u* e2 D% Y1 T
  390.         CE_High();                                /* disable the device */
    * C* D; T5 \( D! f9 q3 t
  391. }
    5 u" ?1 Y3 f& ?- R0 N
  392. + f: @( T! O% G9 Z2 R
  393. /************************************************************************/% a# b" h+ ]" Y/ g$ N! _
  394. /* PROCEDURE: WREN                                                                                                                */
    3 O, e3 }' L" _
  395. /*                                                                                                                                                */  k4 F2 @8 [) O/ T. C
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    ( U9 h3 E2 j. a
  397. /* to Enables Write Status Register.                                                                        */6 [# E8 a5 @5 ?6 S2 \- F# p
  398. /*                                                                                                                                                */, K7 w/ H$ l# B) X& k
  399. /* Input:                                                                                                                                */
    : i3 G* a2 _8 l! M( f" o( ~8 T5 B
  400. /*                None                                                                                                                        */
    ; U  r; o1 F' Y  B: e
  401. /*                                                                                                                                                */
    9 N& o8 O3 g; B6 x9 @% N0 e5 q
  402. /* Returns:                                                                                                                                */- t& G! m8 R$ D$ D' s, N( ~7 M' F
  403. /*                Nothing                                                                                                                        */
    ) s, W2 T# j6 o6 X8 n$ d! U
  404. /************************************************************************/, |4 _, z& }  z) l2 O& W  O8 ?% {
  405. void WREN()3 z  R& K' o" _+ K4 q# [+ z
  406. {
    ! O) l# r3 \/ @# }
  407.         CE_Low();                                /* enable device */, J' F% S. y3 N* _. X8 r8 K
  408.         Send_Byte(0x06);                /* send WREN command */
    ) @' g) g9 h7 v+ }6 @* T; [6 Q
  409.         CE_High();                                /* disable device */
    ) z1 V4 b7 {2 l  k$ e( e- j  `5 m) l
  410. }
    - f7 d+ h! K) @7 s4 C
  411. 5 m0 @- M# _$ J  s0 k
  412. /************************************************************************/
    ( d4 p8 s: `6 E6 }2 E* i# A5 x5 P
  413. /* PROCEDURE: WRDI                                                                                                                */
    & }* G% G4 t. T
  414. /*                                                                                                                                                */3 ~& r8 \: M- W1 z
  415. /* This procedure disables the Write Enable Latch.                                                */
    - x7 ?$ z. \3 n
  416. /*                                                                                                                                                */
    4 i: p4 q0 m( g# @/ F% s' [2 s
  417. /* Input:                                                                                                                                */
    ( w. u. K4 ]; P
  418. /*                None                                                                                                                        */
    ! S8 y6 u  ~- s- O% w
  419. /*                                                                                                                                                */
    , |, u, N- c: Z/ B7 `# E
  420. /* Returns:                                                                                                                                */) d0 L: r' A/ |, T3 h
  421. /*                Nothing                                                                                                                        */
    . k) [) m3 y) {2 y  |) I+ h! L
  422. /************************************************************************/
    / x6 [$ B' Q8 b& n6 u- H$ g# o; G
  423. void WRDI(). E: z+ i: n/ q
  424. {
    # K! x, p/ ?9 l7 i
  425.         CE_Low();                                /* enable device */: u* e' k6 j5 V
  426.         Send_Byte(0x04);                /* send WRDI command */
    . ?" h3 ^4 s- X7 v4 c
  427.         CE_High();                                /* disable device */
    , h( h  ?% h, v
  428. }
    ! g# L' ]) {  k! }) V
  429. " ~8 U2 E! B& v6 K
  430. /************************************************************************/- K2 o; P; C. s5 d0 s: n2 E. e
  431. /* PROCEDURE: EBSY                                                                                                                */4 v9 ~6 Q& @0 O
  432. /*                                                                                                                                                */" l# v+ x2 [& i$ K
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */' w" G2 h5 j. M5 A, i7 _6 w
  434. /* programming.                                                                                                                        */
    " L9 W+ z; O' G1 N
  435. /*                                                                                                                                                */5 \+ k# q( Q4 _
  436. /* Input:                                                                                                                                */5 N5 L; n" y. D) z' Y+ r
  437. /*                None                                                                                                                        */
    , ~& C. p/ i' i4 v& d
  438. /*                                                                                                                                                */
    3 Z" s+ ~" s# `/ E: W
  439. /* Returns:                                                                                                                                */6 t6 `8 W0 f& ]% }0 L0 }0 _5 Q. v
  440. /*                Nothing                                                                                                                        */
    , S" ^1 B7 J. P8 N
  441. /************************************************************************/
      S6 s- z9 o- P
  442. void EBSY()
    & J% f5 X; m% _. U( r  G& n8 n
  443. {
    ; }" _8 B0 ~! ^, g$ B3 z) ~
  444.         CE_Low();                                /* enable device */5 ^; M( d! m  |
  445.         Send_Byte(0x70);                /* send EBSY command */
    ; f1 p5 v2 g1 b# Z6 A
  446.         CE_High();                                /* disable device */
    $ W! _' l+ F" f8 N& \/ ^6 \
  447. }* S$ _( e% `1 z4 M+ k; E
  448. " R7 V' \* |3 F4 y" G+ r, t) ]
  449. /************************************************************************/
    : o- k7 }2 t  t- K
  450. /* PROCEDURE: DBSY                                                                                                                */1 W; [: R- E* t1 s& ?6 a
  451. /*                                                                                                                                                */
    . D$ A& N$ L4 s, O) J6 M
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    ( P. J; Y4 p: p7 ~$ o' E
  453. /* programming.                                                                                                                        */
    2 T! {7 |# q' l  W5 V" [/ ?
  454. /*                                                                                                                                                */7 H- h: V. t' e+ `3 V$ F
  455. /* Input:                                                                                                                                */
    " v, N- [2 x! U! O4 T1 g* ~
  456. /*                None                                                                                                                        */3 i1 r' ^4 e8 s
  457. /*                                                                                                                                                */
    3 H6 g, |7 k: E5 {" G
  458. /* Returns:                                                                                                                                */
    9 S# W, a5 z5 z7 l; B; {
  459. /*                Nothing                                                                                                                        */
    4 x1 G( d! Y- u; U
  460. /************************************************************************/& g0 O$ b" o& h. K+ j- M
  461. void DBSY(). |# z: i* ~/ X: C
  462. {
    + ]. J# u; u: z0 o5 K
  463.         CE_Low();                                /* enable device */7 r' @- N" g3 A: j! Z+ m+ W! ^% E
  464.         Send_Byte(0x80);                /* send DBSY command */# n" U. v1 ^$ a/ x7 `3 c
  465.         CE_High();                                /* disable device */" F* v. ^9 b# M3 _
  466. }- I8 [7 Z2 p! T# Z1 p% c; A- |* ^3 H
  467. , u% N# [: M' p
  468. /************************************************************************/# \1 v4 I: h; j" P" ?# ^2 P
  469. /* PROCEDURE: Read_ID                                                                                                        */
      Y% G6 J* c: i/ r
  470. /*                                                                                                                                                */
    2 _2 z. F$ }1 P2 b5 f
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */% z/ B$ y( H$ _* Y3 a5 j
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */- `% y, E& n: z5 C, P  N* D
  473. /* It is up to the user to give the last byte ID_addr to determine      */1 s: K. e- t" G
  474. /* whether the device outputs manufacturer's ID first, or device ID         */5 }& ^2 @, K- X% b
  475. /* first.  Please see the product datasheet for details.  Returns ID in */+ V2 Z. ^' ^$ J* `  a4 H
  476. /* variable byte.                                                                                                                */" H0 V/ I, c4 l. g9 {" }
  477. /*                                                                                                                                                */
    ( ?4 K7 E  L  V+ e* U3 ?3 w
  478. /* Input:                                                                                                                                */
    & U$ k1 E( @3 E) d- U- I
  479. /*                ID_addr                                                                                                                        */
    ( ]: M1 Q! g3 q) g- x
  480. /*                                                                                                                                                */4 W( u! F8 l; F- G2 f
  481. /* Returns:                                                                                                                                */" N+ O4 f; t6 i3 d0 A$ u( K
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    + x! D9 A  ~$ y; v  @4 [
  483. /*                                                                                                                                                */
    . g: j1 Y, R6 A+ e/ k
  484. /************************************************************************/
    , N4 t) I% j9 R% z
  485. unsigned char Read_ID(ID_addr)6 S% F  A4 A- f1 i8 P1 ^& k
  486. {
    4 z& m. }4 a, N+ I/ J8 Q: }
  487.         unsigned char byte;
    ; _% q& h* c$ @- u) }" I3 h5 Z
  488.         CE_Low();                                /* enable device */6 y( ^/ J8 Z$ G0 d, z2 y
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */* w7 H4 O& @1 G# {# U+ p% L/ z
  490.     Send_Byte(0x00);                /* send address */, h  V3 g0 Y* k2 H
  491.         Send_Byte(0x00);                /* send address */8 S8 |% N. P7 D1 a. s" Z  Z$ Y
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    ; F% J4 Y1 g! Q6 d" D9 i4 o+ I
  493.         byte = Get_Byte();                /* receive byte */9 p0 `8 d" [8 u  j& L" ?! F+ V
  494.         CE_High();                                /* disable device */4 Z9 r# B0 ?0 T. ~9 r
  495.         return byte;
    ; R* p( c7 G4 d0 i
  496. }
    # j; Q5 Z. V. T" p1 P  C

  497. 0 O' M5 j4 ~6 y. \- N" @
  498. /************************************************************************/1 M* R6 n7 P+ }' x+ c- j
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    $ F; \5 U  Q( o- I3 L  Q4 B6 H+ [
  500. /*                                                                                                                                                */. f+ W& N- b7 P! ]6 J7 }& q
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    ' l6 a- D# I0 Y+ p6 P5 O' z
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */4 A$ \( L0 y  y  K+ j6 d
  503. /* Please see the product datasheet for details.                                                  */3 h; I0 d$ q7 X$ N7 s- d8 D7 k
  504. /*                                                                                                                                                */, b8 ]: K8 {5 A8 I& H
  505. /* Input:                                                                                                                                */
    9 \) I7 ~" K& _
  506. /*                None                                                                                                                        */
    # J; S$ t0 T/ ?+ b
  507. /*                                                                                                                                                */3 m  b! j( Y! w7 H3 x
  508. /* Returns:                                                                                                                                */, G& H/ T& g& r
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */' ?4 y  e! g2 z1 K, W/ ?5 G! Z* Q
  510. /*                 and Device ID (8Eh)                                                                                        */5 y. Y1 @/ d4 y! T0 K3 c. ^2 B
  511. /*                                                                                                                                                */
    % `7 s, l4 A4 O1 J1 v# \
  512. /************************************************************************/9 h2 E* S3 q: z- \% U
  513. unsigned long Jedec_ID_Read()
    $ T/ Q6 k% Z2 v5 O4 j; g& h
  514. {
    ' p) q: ^' u% U7 ^+ U; N
  515.         unsigned long temp;+ k1 O' X+ v) U* w
  516.         - g6 X# k& m# N; e4 v! @$ ^! Q
  517.         temp = 0;
    " W1 ^4 u  z8 g* r
  518. * `( @  p- H% f; [# q; L; X1 y5 c& H
  519.         CE_Low();                                        /* enable device */
    # d8 X: _- [  s# |  E( }! s6 ~
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */' G: h3 J2 Q% Y+ ~/ C( ^, E# C
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */6 C7 B, @: r1 B4 D6 {  N
  522.         temp = (temp | Get_Byte()) << 8;       
    9 Z; M4 b  H1 \, P1 }* _3 i. I0 a
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */  I, H5 S4 y; k
  524.         CE_High();                                                        /* disable device */; \( K" L* D" z: O: r% X9 K6 Z

  525. 1 B; S6 u9 s/ j5 a7 E
  526.         return temp;
    ( [3 s) {2 f4 ^" s* p
  527. }: G3 B/ ^' G2 [* @6 P
  528. ' _3 W! w- {5 I+ e: p
  529. /************************************************************************/" b* k: e' P! G# L2 Q
  530. /* PROCEDURE:        Read                                                                                                        */' r  _9 x+ X+ J- k# F. [/ ^$ d/ ^
  531. /*                                                                                                                                                */                / L3 L8 E! }- x
  532. /* This procedure reads one address of the device.  It will return the         */1 Q, `7 I2 b& C8 ?% H+ j4 }" P5 Q
  533. /* byte read in variable byte.                                                                                        */
    5 Z* F: b1 ^* `
  534. /*                                                                                                                                                */( s- E! p9 J: ?* p' Y
  535. /*                                                                                                                                                */" P' |* ]; ]0 H
  536. /*                                                                                                                                                */
    ' {' f' _+ o- t! U" `: T9 T9 U4 g; a
  537. /* Input:                                                                                                                                */
    # Y! U: c7 F7 n8 P: ~1 ~4 Y2 D4 j
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */9 |1 v6 S$ X/ |8 ^) [; k
  539. /*                                                                                                                                      */& o* O% L# e0 j  l9 x
  540. /*                                                                                                                                                */
      I+ O; ]: ?  W- P; g# r% Z
  541. /* Returns:                                                                                                                                */0 o$ V: L1 U. m9 k# I- C
  542. /*                byte                                                                                                                        */$ y8 k5 I1 Y) ]+ n( G" g
  543. /*                                                                                                                                                */
    7 w. q( z" h! c+ }3 O% M: P( a
  544. /************************************************************************/3 D1 L$ N$ u& p" F5 Y( `
  545. unsigned char Read(unsigned long Dst) 9 X7 o# K, f  S* Y3 u
  546. {( ]' P. e5 v9 u5 ?5 H+ w
  547.         unsigned char byte = 0;       
    ! d( V4 E4 D$ d; Y
  548. 6 D- Q- R1 d0 d" s' y
  549.         CE_Low();                                /* enable device */
    $ k+ W7 F7 ~. J+ |3 U- q
  550.         Send_Byte(0x03);                 /* read command */
    3 N0 E" `# B5 o) S7 w. G7 ]
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */# c3 @. k% S# ?8 b6 O% ~, a
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    , J! m5 E# @$ t5 V
  553.         Send_Byte(Dst & 0xFF);  b" ~3 G: s/ j: `2 g) [
  554.         byte = Get_Byte();' G3 M* ~6 C0 u
  555.         CE_High();                                /* disable device */8 o' v! v6 b8 M" T0 e0 N8 d
  556.         return byte;                        /* return one byte read */  \- L$ i5 ^1 ?/ Y" N; i
  557. }
    6 z, B  y0 U! G

  558. # P1 Y) @- D  \1 y6 @7 y
  559. /************************************************************************/) `6 H5 |/ z! t1 L
  560. /* PROCEDURE:        Read_Cont                                                                                                */; g* q% C, W* j* D
  561. /*                                                                                                                                                */                5 p3 |: ?1 ]* q% {' t, ]0 M) s
  562. /* This procedure reads multiple addresses of the device and stores                */
    $ _6 |8 O9 I4 Q# `' X; f& L
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/: f  j  n0 B/ C! O* l& j$ C) R
  564. /*                                                                                                                                                */! T: ]& G5 ~( g6 u, y& i) H2 Q9 w
  565. /* Input:                                                                                                                                */1 i9 n& b1 {+ o' l# J  j
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    4 c' z/ E1 E2 k
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    " a6 t0 D8 ]0 l! C3 B2 t
  568. /*                                                                                                                                                */( N/ y; r% U8 U0 h4 P
  569. /* Returns:                                                                                                                                */" }$ W  L( R* Q1 x4 ?" N6 {
  570. /*                Nothing                                                                                                                        */
    * D% O; t5 H  U9 t
  571. /*                                                                                                                                                */. S+ ]! P& J' s# ?9 ~' ~
  572. /************************************************************************/
    & H. v- ]& E9 z. M7 X- Q
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)4 e, V% J6 a% D) z
  574. {* Y& w( W; W. W' J
  575.         unsigned long i = 0;
    9 j2 p6 K+ R  Q+ {# i& `
  576.         CE_Low();                                        /* enable device */
    : ?8 {- }9 K" g
  577.         Send_Byte(0x03);                         /* read command */. F: U5 E3 y6 [3 U' R
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    : t: N2 I1 Y) z" i
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));% V, v3 @& G1 w& S( r
  580.         Send_Byte(Dst & 0xFF);/ J6 A! u( `' n
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */7 P) l9 x1 k4 w' a
  582.         {
    : M* Y! e6 S- N' z
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    ; Z- \/ l! E- g+ J
  584.         }
      m  h$ ^: e- l/ `; O/ c
  585.         CE_High();                                        /* disable device */
    0 y% S0 C9 h" M- D4 F
  586. * K0 a- v$ ?% x0 h* f
  587. }. N- n8 l* S& ]+ U3 b
  588. ) {' }7 Z1 r. U. c' |$ A: ]5 W1 _
  589. /************************************************************************/5 \' I# F% ~8 [8 e7 I' \2 G1 b$ X
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    2 Z! O6 }  B' p7 u
  591. /*                                                                                                                                                */               
    ' O9 K# D8 ]' ~
  592. /* This procedure reads one address of the device.  It will return the         */
    1 P2 E) F, [% |. k. e' b
  593. /* byte read in variable byte.                                                                                        */+ L, v0 x0 S9 [1 z9 j
  594. /*                                                                                                                                                */4 {( z% t4 p. |" U) n* {, d' T+ V
  595. /*                                                                                                                                                */
    8 \) M5 P% I2 J
  596. /*                                                                                                                                                */
    + x8 b5 K  Y. A+ b, c- d) R, m5 j
  597. /* Input:                                                                                                                                */
    6 E, ?$ q. ^" _# i- b# |
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */8 v( K* y! Y. M' I+ S
  599. /*                                                                                                                                      */7 [; m: p0 h1 D' t
  600. /*                                                                                                                                                */
    ) J0 A: f, r. z6 N5 t
  601. /* Returns:                                                                                                                                */6 v, k1 R4 F" M- q
  602. /*                byte                                                                                                                        */9 M9 {( K( g# u: f6 f! P
  603. /*                                                                                                                                                */
    . ^4 M0 A# r3 x  k, q3 C! s( U3 @
  604. /************************************************************************/
    ; F% C7 m# D8 g
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    / E; i; Q; ]8 u( ^& N0 M3 L* q
  606. {
    / e$ B- [! [: E4 [
  607.         unsigned char byte = 0;        3 _7 U$ _+ o9 T, X

  608. / d7 r# c& G& X6 w9 y
  609.         CE_Low();                                /* enable device */
      G; H1 s: L3 q) l
  610.         Send_Byte(0x0B);                 /* read command */
    8 z7 p- h8 z* i; ~5 E1 O
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    + X# z7 J( o; c( y6 f
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));2 G$ Y; `8 M! Q
  613.         Send_Byte(Dst & 0xFF);3 I5 a+ V  W1 q9 @, |
  614.         Send_Byte(0xFF);                /*dummy byte*/
    + G0 R: x) [7 }' Y* n/ P$ I
  615.         byte = Get_Byte();3 z. t9 h; t. l8 t1 ~0 E' ~$ e
  616.         CE_High();                                /* disable device */( }6 q0 f1 ]6 x/ s
  617.         return byte;                        /* return one byte read *// G. _, e' B; P+ W$ z% u/ i
  618. }
    % O) ?3 k4 W$ E" Q+ x, u
  619. ! q5 k/ X7 F" i( E2 m) |6 r% ]( j
  620. /************************************************************************/
    ( J6 Y( D7 W' T- _, V
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */4 g) K3 d3 o3 F
  622. /*                                                                                                                                                */                2 G7 Z/ H( o4 T+ u; ^# m2 h6 x$ f: F
  623. /* This procedure reads multiple addresses of the device and stores                */
    3 r3 l; j" B+ C6 }2 c- H4 J
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    - H- O( J& x0 M/ A/ c9 y2 ]) ~
  625. /*                                                                                                                                                */
    / ?6 E/ J( L3 i" M0 c3 [
  626. /* Input:                                                                                                                                */
    5 q( f4 A0 T: c* w0 F8 q
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    7 c: s/ w/ g/ C  i! O
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */5 ]! ?4 [* z& G7 ]* [! ]  {. y
  629. /*                                                                                                                                                */
    1 }' ?& o. n7 y- H. k7 K
  630. /* Returns:                                                                                                                                */
    5 l; O* v- P" C3 K& \
  631. /*                Nothing                                                                                                                        */
      g9 B2 W# p$ w  O5 S/ O1 N
  632. /*                                                                                                                                                */3 L! _3 E; D, A' R* Y9 F
  633. /************************************************************************/
    ; S/ i3 N/ ]$ H
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    1 b. X# x: [/ i7 _; D: ]
  635. {
    - N: d; G% n: z5 Z# j/ A/ _) W
  636.         unsigned long i = 0;
      D) N2 \: Z( z- \, a5 O. B
  637.         CE_Low();                                        /* enable device */
    3 n. m0 }- Y! G1 f5 v3 t* e7 x
  638.         Send_Byte(0x0B);                         /* read command */
    5 v: p  E% H3 d1 y; ?! E
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! y! }6 y& V) Z: |0 u7 e7 f$ {
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));  P# I; C+ F* R" L! i4 C2 _
  641.         Send_Byte(Dst & 0xFF);, T. W4 _8 j" e& A; P# A; l
  642.         Send_Byte(0xFF);                        /*dummy byte*/; E) @% p( w/ R* M0 U/ e% _
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached *// ^6 e8 e9 T; P2 x
  644.         {
    ; ~8 `. O4 f. i3 T
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */, g0 E% ]5 C) o! ]1 }% c
  646.         }
    1 k5 k3 G' v/ ]1 N7 k" ]
  647.         CE_High();                                /* disable device */% }$ |0 Y% ?% k
  648. }3 O+ v7 c# e- J" A/ j' Q4 I

  649. ; X: L( R, t% H; t2 Q4 d
  650. /************************************************************************/
    % Z/ p. ~1 [6 }- G% C- y* `) r
  651. /* PROCEDURE:        Byte_Program                                                                                        */' N6 Q+ B; [+ r6 v7 u" B, W3 U/ I
  652. /*                                                                                                                                                */( m+ H2 |8 B  x$ k! v
  653. /* This procedure programs one address of the device.                                        */
    . V! R* X' g$ s/ G" w; E8 i
  654. /* Assumption:  Address being programmed is already erased and is NOT        */" \6 i2 C* Y2 N) D+ c, u, J, h
  655. /* block protected.                                                                                                                */
    9 ], [# g: n1 s1 I2 M$ q; z8 d5 b
  656. /*                                                                                                                                                */
    ! i% S+ z' V4 A0 C6 t- x- E
  657. /*                                                                                                                                                */
    5 E+ m- N2 ?# @$ C* w
  658. /*                                                                                                                                                */
    7 {( |) D" h8 e/ X. C5 H0 U
  659. /* Input:                                                                                                                                */( n" v8 X; U+ b. n8 `5 v2 J
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */. J) {- e2 |" a
  661. /*                byte:                byte to be programmed                                                                */
    $ A3 g+ Q* W: E1 ]& B, }
  662. /*                                                                                                                                      */+ H% {) ~3 [! }7 e
  663. /*                                                                                                                                                */. r7 C0 h5 d* G5 E. y. p
  664. /* Returns:                                                                                                                                */$ r; j9 v6 t( P8 L: l& R
  665. /*                Nothing                                                                                                                        *// h0 f/ U0 J  Q0 a' ?" U1 K
  666. /*                                                                                                                                                */
      i# S0 F+ }% {: k
  667. /************************************************************************/
    - S; P. Y' B7 B( u% ~) e* {0 K! K
  668. void Byte_Program(unsigned long Dst, unsigned char byte)9 ^, ~$ w' z# o' t: T- N; A
  669. {8 }9 ~* {2 X. A4 Y+ ?: O
  670.         CE_Low();                                        /* enable device */
    $ R# {5 h, j) y. q% [$ s7 a
  671.         Send_Byte(0x02);                         /* send Byte Program command */" U, T6 l7 I5 F+ G
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    . I- B& K' c/ ~  \# U( A
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));0 [0 {7 {1 T% F  w2 g7 {
  674.         Send_Byte(Dst & 0xFF);
      g, F1 p3 h' N# s2 y
  675.         Send_Byte(byte);                        /* send byte to be programmed */! K6 w2 _" ?$ c; ~5 K% j3 o8 W
  676.         CE_High();                                        /* disable device */- V+ f' l" r7 C: U8 P
  677. }* k* C, o+ E: V9 G/ d: n& `# M4 O$ @
  678. 3 ~1 k  E' F4 J0 r& c2 g
  679. /************************************************************************/* F4 I# q' p% @8 t4 f
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        *// L6 Z! _" w( a: p7 c
  681. /*                                                                                                                                                */
    6 }8 L. C" l  Y9 x! {- ~
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/; W% L5 v" e0 p0 [1 x: a
  683. /* the device:  1st data byte will be programmed into the initial                 */; t3 F" \- t& L* @" X5 ^0 S; o! |
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */& P7 m) H9 K; C: p
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    " @, j5 J& b2 K& [
  686. /* is used to to start the AAI process.  It should be followed by                 */; U: q7 p/ ]6 s4 U/ Y
  687. /* Auto_Add_IncB.                                                                                                                */
    ; s3 I8 B2 p: V' R1 E
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    & b1 j( Y; q& u8 y" j  d! H
  689. /*                                block protected.                                                                                */
      S5 }1 N) k  B1 O7 O$ d; t
  690. /*                                                                                                                                                */# V: |4 a+ O3 m! y, _
  691. /*                                                                                                                                                */0 i3 W) R1 s) b# B( y3 U# K
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    & M9 z" `. ~. r0 w
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */0 S9 V+ v0 o. o% z) T2 u' S
  694. /*         unless AAI is programming the last address or last address of                */  r+ I' Y9 }) h" z9 m' ^
  695. /*          unprotected block, which automatically exits AAI mode.                                */. L% m. I1 ~4 B8 T0 j
  696. /*                                                                                                                                                */
    & f5 {: H% k/ s3 H2 P' \& ~! c% x
  697. /* Input:                                                                                                                                */
    # \2 z3 x& x" a: v% V* f5 P1 z
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    , o% B, o( _7 [# B: `( s
  699. /*                byte1:                1st byte to be programmed                                                        */
    ) @* B/ W9 r7 d6 l) D4 K6 x/ @
  700. /*      byte1:                2nd byte to be programmed                                                        */+ I. j) `% W! h2 G& |7 j
  701. /*                                                                                                                                                */* {0 Z5 `, Y* e& N5 a
  702. /* Returns:                                                                                                                                */
    - Q( H; C4 e2 l' Z9 d
  703. /*                Nothing                                                                                                                        */
    ) \6 g: O; ?; ]/ j) A8 ^
  704. /*                                                                                                                                                */
    . |7 j( I% n0 y; P$ F4 F+ R" N
  705. /************************************************************************/) f9 l8 U; Q4 I! E
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)* ]: L( r! P& O& L2 w
  707. {. B6 T, S* O# x6 w6 I5 o, y
  708.         CE_Low();                                        /* enable device */2 d, c5 w3 ~, L
  709.         Send_Byte(0xAD);                        /* send AAI command */
    . z2 Q! c; M% n6 @
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */, C. Y5 V' O( I9 ?+ |" t& g+ d3 l& `
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));6 U$ k5 X4 G# W  t/ q
  712.         Send_Byte(Dst & 0xFF);
    ' P) [, H* z% g5 M- c& R
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    " F  y2 ?9 E) U6 W  _8 Y
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    7 E2 H1 @8 v/ M6 x0 i
  715.         CE_High();                                        /* disable device */- l7 m" j5 }* \& t5 @5 h  e7 y
  716. }
    2 n5 E2 w  x4 X6 f4 |2 j7 B
  717. % B3 ^+ ~# w6 o, |# Y
  718. /************************************************************************/
    9 F! C. Q0 E. P. x; W' U
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    " W0 V& g) O3 Q8 Z0 C$ i2 T  N
  720. /*                                                                                                                                                */. u5 H) x0 E# P: j; @
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    : j. E: i3 e/ M* I- E; Z4 A0 [
  722. /* the device:  1st data byte will be programmed into the initial                 */
    ! g; d" Z) E0 V) a! M+ E
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    $ G/ s+ t( E. P4 u9 T; R/ j
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    ; D: H' a( q, ^2 b
  725. /* is used after Auto_Address_IncA.                                                                                */
    5 ?! a% {0 [9 D8 A6 {
  726. /* Assumption:  Address being programmed is already erased and is NOT        */  V! E& f7 h6 k7 x- ?+ v
  727. /*                                block protected.                                                                                */* y2 w# y6 I/ Z( v. s; \& c
  728. /*                                                                                                                                                */
    ) H9 D5 A+ |& Y8 U' `3 }$ U
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    * x5 D( e& N0 K
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    9 ^+ g2 {8 g3 R, \
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */0 e- y1 @: o+ `* t
  732. /*          to exit AAI mode unless AAI is programming the last address or                */0 d2 `( z( C6 v% z" h
  733. /*         last address of unprotected block, which automatically exits                 */- @$ T$ ?. O7 j/ v! T& K
  734. /*         AAI mode.                                                                                                                        */
    3 W5 {6 ~) z) G% g0 \( o
  735. /*                                                                                                                                                */
    4 t& v: F3 I$ E7 k+ k5 k: q
  736. /* Input:                                                                                                                                */+ l" ^8 `$ K# ^) ^# W
  737. /*                                                                                                                                                */
    " d% y  ^0 a- _
  738. /*                byte1:                1st byte to be programmed                                                        */# _4 N" G0 A) E' O8 e# g3 R4 Y
  739. /*                byte2:                2nd byte to be programmed                                                        */8 O. F8 f! O+ {# e
  740. /*                                                                                                                                      */" r( z9 E6 {' q" R: k# j/ M$ Z8 ]
  741. /*                                                                                                                                                */
    9 O% ?3 Z2 E# Y1 W5 i
  742. /* Returns:                                                                                                                                */
    ; N& y6 E/ }+ x, J8 J3 O! v6 N7 S
  743. /*                Nothing                                                                                                                        */
    ; ^5 W* N& o1 n2 ~% _# n; N
  744. /*                                                                                                                                                */: P; j; P) v/ _' C& ^+ x0 n0 ?  C
  745. /************************************************************************/
    " T/ ~, F% Q! j0 J7 E/ X, p) l
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    + l7 E3 c$ h# {6 z! s) x4 D
  747. {6 [6 `, }* s4 b4 e
  748.         CE_Low();                                        /* enable device *// s4 W1 f9 A1 E  q
  749.         Send_Byte(0xAD);                        /* send AAI command */
    , B0 {% \" n4 T8 c! c
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */4 ]; }! [% W: D, f2 S% J" h
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */7 k) ^. M+ b0 a$ ^8 B5 Y
  752.         CE_High();                                        /* disable device */
    ( _) `7 T. s# s
  753. }
    2 e$ G; i  j" Q9 @7 Y' N

  754. & ^9 ?9 t; f9 X0 D( k6 Q4 i1 N
  755. /************************************************************************/3 j' I; R  X) Z7 k3 P7 a! B
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */; c! B  U0 x: s
  757. /*                                                                                                                                                */
    * @5 d& ?& I  c/ l) {
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */4 G5 s  W  J- C9 h" b' \/ }0 R
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */& K& W+ O2 h, `7 A2 H
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    ; C1 l9 _" r0 U( v
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */  F: o# [9 Q3 d% S; m2 ~& U# Q
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */+ i5 I5 G* N/ i$ F' F) G% s8 O
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */) B5 A/ f3 T( H, a# w
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    3 I0 @8 K% ?6 i. l3 K, U
  765. /* Assumption:  Address being programmed is already erased and is NOT        */) K, _; Y( @9 Q8 M% ]  F( E
  766. /*                                block protected.                                                                                */
    % W0 M8 a" Q/ O; D: Q3 C
  767. /*                                                                                                                                                */" b0 |- O# c5 Q% X/ B7 H7 _
  768. /*                                                                                                                                                *// t! n6 R: ^: f" ]
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    . K9 J! |. o: U; P" s: r- w. S
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    % D: U9 m" f1 P, t
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    1 O1 |- P1 W, G0 q. [& g
  772. /*          to exit AAI mode unless AAI is programming the last address or                */- i7 r$ z$ O* f
  773. /*         last address of unprotected block, which automatically exits                 */& }) r, P: f% ~1 ~
  774. /*         AAI mode.                                                                                                                        */  d7 T# q4 I5 K' x
  775. /*                                                                                                                                                */# T: w$ \$ B/ q4 R0 `
  776. /* Input:                                                                                                                                */# L5 w/ }) `* J. k( C3 X
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    6 K" e1 E- h; G' g7 u* s' K+ o6 M
  778. /*                byte1:                1st byte to be programmed                                                        */' X6 s7 l4 K- v$ g0 M) }. b" ^9 U
  779. /*      byte1:                2nd byte to be programmed                                                        */- N2 B( l+ c3 ?5 j  j# ]" U) @
  780. /*                                                                                                                                                */" e& P% O" r1 K) d% v% g
  781. /* Returns:                                                                                                                                */$ J+ g+ X3 [. K
  782. /*                Nothing                                                                                                                        */
    , G( R8 S# e& w  F* r7 Y
  783. /*                                                                                                                                                */
    8 L8 z, W0 U& j: ^; b$ x4 O
  784. /************************************************************************/$ V& V( K9 b/ Y6 a: X
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)9 [! A9 f6 s9 R- A( `9 `
  786. {
    3 F( P% V& [' Q
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    2 w% y6 r/ f& A; `  _  p2 M! p2 l
  788. ' M0 E: k# L# |) C: Y% s" w
  789.         CE_Low();                                        /* enable device */
    % R& c7 B. \  L* M4 `! i
  790.         Send_Byte(0xAD);                        /* send AAI command */
    # g# _  E/ r9 i0 z; G
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ' m7 c6 C$ M2 Y+ a+ F3 |% o
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));  d4 n& m3 S. i! e
  793.         Send_Byte(Dst & 0xFF);( l0 q* m0 G. W& ?
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        3 u3 h, |+ M% z9 G( H9 o6 E$ i
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */& z3 N8 ^/ G' w3 ^. p! y1 ?8 |
  796.         CE_High();                                        /* disable device */1 v. o9 i7 O) [! L) S7 F1 l
  797.         + C8 `! R8 c- G- r. Q
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    % ?6 o: w# q/ }5 Q6 e" A0 a1 @

  799. & `& d, O6 |1 N( H" [" w
  800. }
    3 _& f( E+ `2 \& o) l4 T3 D# W
  801. , N0 ?8 R7 i8 f
  802. /************************************************************************/
    4 s' j0 N0 w3 I' Y9 ^5 J
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                *// g6 s  ~8 C4 S3 r5 s1 v
  804. /*                                                                                                                                                */2 q" [5 x' T: F$ x8 x% A1 [% |5 p
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */5 v3 c2 K# F$ v, n4 o2 O! t" `' f3 X- Z
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */* x/ I' W9 F) h. X% a5 F
  807. /* AAI programmming is completed.  It programs consecutive addresses of */- U8 s* X  A& u% O
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    2 W# q8 x' P; @, L! _) q
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    9 x' X# n5 b% [: p. q! T; \6 b6 ~- Z
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    : e. Q8 r" X5 s3 d7 F2 v
  811. /* used after Auto_Address_IncA.                                                                                */9 m+ c' d9 n& z. y4 B1 A
  812. /* Assumption:  Address being programmed is already erased and is NOT        */& F" }( _4 H) ?* D; A
  813. /*                                block protected.                                                                                */
    " K; s# X* n& J  [: \' o, F0 |7 R9 i
  814. /*                                                                                                                                                */7 _- S8 M: Z- ^) A3 s
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    & `; i# d( U9 h% G
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */8 q8 e6 U. E/ g1 P, w
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ; n; u4 g: }' H. }6 {
  818. /*          to exit AAI mode unless AAI is programming the last address or                */; Z: H6 V& r! i1 c* ~
  819. /*         last address of unprotected block, which automatically exits                 */2 G" J) }5 h) N7 w% E, ~
  820. /*         AAI mode.                                                                                                                        */
    ; P6 h) a7 E) j! c6 C) M; S' N
  821. /*                                                                                                                                                */" ~& ?4 x" Z! t( e: j  A0 ~& ^
  822. /* Input:                                                                                                                                */
    8 t% G* Y" k1 x  K+ O& F( I* h# w
  823. /*                                                                                                                                                */8 \" X3 o& m5 H  f
  824. /*                byte1:                1st byte to be programmed                                                        */
    ' C( q* ~- \; m5 k2 K( _
  825. /*                byte2:                2nd byte to be programmed                                                        */5 K& p5 R# y$ M: [
  826. /*                                                                                                                                      */& I7 o8 Y6 R9 L' K# m
  827. /*                                                                                                                                                */# T7 S% z- S) y8 [8 B6 y
  828. /* Returns:                                                                                                                                */. v' E: e% u" M3 y3 @+ q$ P3 n' @
  829. /*                Nothing                                                                                                                        */9 n/ A3 _. d2 I" h( L5 u9 ?. s3 Z
  830. /*                                                                                                                                                */
    1 o3 r+ K6 y# Q
  831. /************************************************************************/. ~8 z) `9 L. G! A
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    ) r# l3 N5 V3 j5 i0 E+ p1 l
  833. {6 c1 B, j; B. h# b6 n
  834.         CE_Low();                                /* enable device */
    6 |8 M3 i1 z' L4 }+ E& a5 ]
  835.         Send_Byte(0xAD);                /* send AAI command */
    # R" ]: f  N/ r5 J
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */0 X2 C7 Y! z7 U  p: Y, _1 M9 y
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */. [" g1 w  k% G1 L
  838.         CE_High();                                /* disable device */: I) w& R/ c! s
  839. ( r: o) p* `8 {; e' b# ?" t5 p7 |
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    6 u; r5 l* H" W- l* g0 V

  841. 8 x8 P! K1 d, [
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    / K$ m& [) F, ]9 Y, M3 D
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    ' n( n3 K+ g# D* ?- \
  844. }7 P- V# t& |8 _$ w+ W

  845. + C8 X+ ?2 r# S6 s
  846. /************************************************************************/
    4 N+ ^# k$ q' I9 B1 r
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    6 `  T4 U$ p( c. P) P7 ]
  848. /*                                                                                                                                                */& _# ~. S3 f" |6 H  g' R$ q
  849. /* This procedure erases the entire Chip.                                                                */
    ' u, o" o9 M: h5 A+ G# p- S
  850. /*                                                                                                                                                */# G- U, f4 U3 A: L0 k$ \% [6 u
  851. /* Input:                                                                                                                                */
    ( f/ j5 C/ B3 S% h5 t
  852. /*                None                                                                                                                        */4 i4 A7 i  B% W& S; @. B
  853. /*                                                                                                                                                */, l; `5 Y1 s, A' ^2 W; a6 P8 D( A
  854. /* Returns:                                                                                                                                */
    4 l( u8 A2 @) ?9 ?5 U' q
  855. /*                Nothing                                                                                                                        */3 v& g, b6 @+ _$ u1 i+ b- g
  856. /************************************************************************/3 J: Q* f) C2 l$ ?- C7 k
  857. void Chip_Erase()
    : k/ h" p3 E5 _; |9 U
  858. {                                                ) Y) m9 a8 j# W2 _
  859.         CE_Low();                                /* enable device */( x3 B& s/ N2 e" G# x% T% y
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */' L* z2 [+ C1 n6 J; M: ~5 ]
  861.         CE_High();                                /* disable device */5 }" c6 B  B+ ?, G- F' Y" }) X- X" N
  862. }3 \9 X# I7 t3 u6 B

  863. ' D. T% E; t3 l. M& p% }
  864. /************************************************************************/) D6 D2 T; o$ c- P6 K# F2 w
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    * S/ A9 j1 U2 P5 P& X
  866. /*                                                                                                                                                */
    . \9 k3 o# P+ ~  D! M* }
  867. /* This procedure Sector Erases the Chip.                                                                */, O. C9 n1 l7 F
  868. /*                                                                                                                                                */# y1 R1 W" q9 B. D" W% {) \
  869. /* Input:                                                                                                                                */2 {3 M- I# O8 b2 \& S
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */' `) J- F1 S4 a8 }+ e- k1 `2 _
  871. /*                                                                                                                                                */
    " ~8 x  J: b! K3 y
  872. /* Returns:                                                                                                                                */4 {8 z. Z1 H) G; \  O; y; f! H
  873. /*                Nothing                                                                                                                        */
    4 \+ ~# \+ H' J2 J# [
  874. /************************************************************************/8 {+ V0 R/ ^. h/ {+ ]9 }9 I
  875. void Sector_Erase(unsigned long Dst)
    " m6 u, u0 D% l, `1 X  {
  876. {: k1 r: D9 w8 j) V- r0 _
  877. * o8 ~# g! j% X+ _
  878. # b0 ]9 ]$ H0 [% K$ f
  879.         CE_Low();                                        /* enable device */: \3 Q! N( X0 g* n* m
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    - q6 w! w/ r" x8 l' c
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */) x( w4 t! H% f
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));: P; j' H1 e7 E& K  }0 t
  883.         Send_Byte(Dst & 0xFF);
      b" X7 j' R" {/ P
  884.         CE_High();                                        /* disable device */7 u+ \$ U; g' j3 Q6 Z2 ]
  885. }        4 G, S6 p# t) t4 D. L! U/ P+ ~
  886.   N0 S; s+ e, q4 y3 e; V# c: W" t
  887. /************************************************************************/8 \7 S3 r2 {4 O
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
      @2 q1 _8 b; i; i% T: S- d
  889. /*                                                                                                                                                */
    3 m! \8 H% t0 b
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */3 z3 U1 `1 d6 d% M& C9 U! Q. T
  891. /*                                                                                                                                                */
    : u* T% l" O: w
  892. /* Input:                                                                                                                                */
    0 B) C) q* p# w: m8 W3 [
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ) n9 ~7 v) P" ^* ]0 C
  894. /*                                                                                                                                                */
    7 H! W" i  y/ \: K6 O! l" M5 U8 w
  895. /* Returns:                                                                                                                                */
    ; _9 X9 q4 w  C6 H+ H
  896. /*                Nothing                                                                                                                        */
    1 y' x, X) o, l) v) l
  897. /************************************************************************/
    ) ]( ], O3 \6 ~% g* q$ X! o
  898. void Block_Erase_32K(unsigned long Dst)
    4 J1 l# i( |/ r! R, f
  899. {# c2 ^& f# F% d% M, ]
  900.         CE_Low();                                        /* enable device */- @! \5 h: Y) n+ }( C
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    $ F  M0 l! g9 F0 Z3 S
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ( n9 |; M: o0 L) b
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));( A# `; @; N% T
  904.         Send_Byte(Dst & 0xFF);- a' G- @# ?, @$ w1 d
  905.         CE_High();                                        /* disable device */
    5 s/ l# j5 R  h. {" d0 S; B5 e+ Q
  906. }
    - D7 k* C9 Y8 i; {; f
  907. 6 [/ o! |0 S, i6 o6 G$ \9 ^' ^7 S, H$ D
  908. /************************************************************************/
    0 z3 \  a& r1 u3 l, Q. l* h! V) D5 ^
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */4 [% [6 V* _4 ~% a: }" `1 p
  910. /*                                                                                                                                                */, I# f; @: m1 l  {6 L" B
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */+ J6 @/ P" a2 a$ B( P9 q9 D/ }
  912. /*                                                                                                                                                */+ C6 s5 y1 }! Y5 ?
  913. /* Input:                                                                                                                                */
    2 k4 c& I3 _, K9 D
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    4 E2 g1 k; S# b! E& q. ?: i4 I
  915. /*                                                                                                                                                */
    & q1 @' O2 I9 o
  916. /* Returns:                                                                                                                                */
    $ B1 _$ G0 |$ R6 v6 i3 I
  917. /*                Nothing                                                                                                                        */4 d+ J" o: ^# `3 W4 |
  918. /************************************************************************/7 h3 r3 G1 ?; ^6 \7 A( j
  919. void Block_Erase_64K(unsigned long Dst)
    ! _2 Z. N' V1 Z7 D/ r; B* t+ Z
  920. {, V# p" [, u* H: h3 Q  t2 J1 f
  921.         CE_Low();                                        /* enable device */
    + `0 v5 Q4 A+ t, h( K. W3 S. x$ ^
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */: ~5 @3 j! [0 a8 w7 E2 V* H
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */4 e2 l% ^1 C1 w7 T; @1 ~
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % n1 b2 U! Q% P7 d
  925.         Send_Byte(Dst & 0xFF);3 R* ~1 h7 e5 F' X
  926.         CE_High();                                        /* disable device */
    # h5 J8 ]. n2 p% ~- p1 B
  927. }
    : V4 D- f$ ^3 \7 {; l$ {( H' `

  928. $ C; S/ U- {- M1 Q0 ?
  929. /************************************************************************/
    ( Z# B1 B0 I, E
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    3 z* X0 r* Y4 ?( v3 d  a/ p
  931. /*                                                                                                                                                */4 A; Y: ?: L+ m3 J0 o, s; l8 I
  932. /* This procedure waits until device is no longer busy (can be used by        */
    4 c$ o5 Z+ N9 x! v
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    4 n8 A  w+ `) |" ~. b( l
  934. /*                                                                                                                                                */
    8 W2 u, h! c9 B& g1 z
  935. /* Input:                                                                                                                                */
    8 X) g; h" G. @
  936. /*                None                                                                                                                        */
    # Q& Z4 ]! @6 C9 \. ]& C
  937. /*                                                                                                                                                */% F2 z7 ]# A* c1 F# P
  938. /* Returns:                                                                                                                                */
    + o$ x$ d: ~# L- M
  939. /*                Nothing                                                                                                                        */  }! G$ k8 \% X2 q' c. a, d/ `; `
  940. /************************************************************************/
    ) @: {# C( Q* h4 e) ?0 l/ b! P' [( L
  941. void Wait_Busy()% ?2 A7 U6 V4 {8 C
  942. {
    7 Y* }: m/ ], q7 z" q
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */+ j! i7 t9 Y, a1 N+ G
  944.                 Read_Status_Register();
    8 P! X7 g, j/ L( m0 w
  945. }
    ' k. K- X6 d  V& D# d" v
  946. ( x3 r" F% J3 E8 o
  947. /************************************************************************/$ f: D0 G7 X6 k9 B
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    8 A# C2 r- u' N( {3 K- y  ?; d& M
  949. /*                                                                                                                                                */( f  a1 B6 L) b  k) {5 y$ Q% U
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    1 p4 M+ ^4 S  p: f
  951. /*                                                                                                                                                */
    : S' Y% r1 B9 Q' c8 U8 o* Q7 I
  952. /* Input:                                                                                                                                */
    ' c& H3 k& G0 l2 R) _1 T$ M
  953. /*                None                                                                                                                        */
    % \0 Q& g7 e# P5 {( X8 m7 q
  954. /*                                                                                                                                                */
    5 i4 r! t4 R4 s( [6 ^
  955. /* Returns:                                                                                                                                */
    1 k! F! e0 A" n
  956. /*                Nothing                                                                                                                        */
    + u0 i: ^* C4 \* \4 v" U
  957. /************************************************************************/* Q8 G4 C! g. Y1 v
  958. void Wait_Busy_AAI(): W* R3 X0 v" }5 V# q- M
  959. {; P6 |; K; P" G: u5 J( J/ G4 h
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    + _! f* G) Z* `9 v. R' Q5 C
  961.                 Read_Status_Register();
    3 b3 y4 G8 V, L, L6 F6 z) W
  962. }' b: D; t: i8 \2 u7 {6 }/ E# K# X

  963. 8 Y& {% ^! d9 H3 q! ?0 m
  964. /************************************************************************/4 u6 Y' d2 l# Z
  965. /* PROCEDURE: WREN_Check                                                                                                */
    " J' p6 _: \7 d8 t# I) ]( x
  966. /*                                                                                                                                                */
    6 x( v  f8 x  s# o4 C8 Q
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    0 J: E8 V" ^3 ]; m5 x6 R; d
  968. /*                                                                                                                                                */6 p" A' b3 C  {2 B- f$ _% u% E
  969. /* Input:                                                                                                                                */9 `3 g8 c5 Q( q/ q; a
  970. /*                None                                                                                                                        */& s/ Q- M) M7 t$ L6 y0 k# s
  971. /*                                                                                                                                                */
    : k6 }7 Z2 _% J9 e: I
  972. /* Returns:                                                                                                                                */( v% p2 D# x  m! ~2 @
  973. /*                Nothing                                                                                                                        */* I* u% J% T& c5 j
  974. /************************************************************************/* ]5 \7 a3 U' c+ s  \; f) p
  975. void WREN_Check()4 t/ T+ P  q# X
  976. {
    * @: |% ?0 ]7 j, \1 K' z
  977.         unsigned char byte;0 d& s' L/ y! e, I- D6 a0 s: c
  978.         byte = Read_Status_Register();        /* read the status register */& A5 Y! W% [) M( T& |) w. ?3 a) A
  979.         if (byte != 0x02)                /* verify that WEL bit is set */; f4 f, L2 ^9 S- H# Z$ h2 X0 @4 E
  980.         {
    2 s* Q- V1 t$ X( E" L% n; a
  981.                 while(1)
    2 f, s3 K# G3 R. s7 O& V
  982.                         /* add source code or statements for this file */
    # F1 m# ?$ j% J4 k/ f7 x
  983.                         /* to compile                                  */3 f& d) U& E+ |! }: ?, d
  984.                         /* i.e. option: insert a display to view error on LED? */* N7 c7 k6 N$ S
  985.                  1 Q2 ^5 ~6 h: @  M( S. ^
  986.         }3 V" v2 O3 Y* \& b: g8 b
  987. }
    $ \* A! _0 z9 c. b8 w0 I
  988. ) i+ {8 V' v* C5 `! O
  989. /************************************************************************// d. \% P. i( w: M  g) _4 ~. r
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */7 G( L' p' n8 y
  991. /*                                                                                                                                                */
    0 V$ B+ X/ v1 \$ R4 ~
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */7 G& c6 f* r# U+ C. d0 [4 R$ X
  993. /*                                                                                                                                                */
    " |* f% }( m& N' W  E
  994. /* Input:                                                                                                                                */
    7 R0 y+ `1 S- R( }
  995. /*                None                                                                                                                        */, V; q3 V+ W: b; s
  996. /*                                                                                                                                                */
    2 l9 }6 [0 I" I) f/ q( p9 E# M
  997. /* Returns:                                                                                                                                */
    4 U2 U$ O1 ]$ j& P
  998. /*                Nothing                                                                                                                        */
    8 b9 I$ v: Q& a  C; T0 S( ]
  999. /************************************************************************/+ _8 N3 [- g% p3 l0 D
  1000. void WREN_AAI_Check()
    & V% M; I% q5 v
  1001. {
    6 U4 e; l% u7 d2 ^  K2 t
  1002.         unsigned char byte;& `, w" ~, d. f1 V$ A
  1003.         byte = Read_Status_Register();        /* read the status register */( |; L2 J% R3 c4 _& }; B
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    1 H: i" S* N$ N  w4 p$ G
  1005.         {
    + }9 N/ C# ~" V4 K
  1006.                 while(1)               
    , x( E' o4 @# b% ~
  1007.                         /* add source code or statements for this file */
    7 e8 v: Q" k" p. M
  1008.                         /* to compile                                  */3 A) l; C. x3 b" ^- i3 E
  1009.                         /* i.e. option: insert a display to view error on LED? */
    6 e/ F, @5 |2 g0 i8 A9 Y% c% G

  1010. : P! o  T2 ?$ R% o! I
  1011.         }& R' W6 U5 t* c/ U- H
  1012. }' W* h! ^; ^6 f5 E( o
  1013. & @) |2 X& F% H0 h7 k, T' C0 b8 u
  1014. /************************************************************************/
    3 P7 c7 t2 ]. d. H+ X! M+ @; l
  1015. /* PROCEDURE: Verify                                                                                                        */
    6 g, N; R* V+ I
  1016. /*                                                                                                                                                */
    4 o: s* S5 `) S/ ?, e
  1017. /* This procedure checks to see if the correct byte has be read.                */# d6 S2 l5 `* t- s0 {
  1018. /*                                                                                                                                                */1 G$ f, R4 v9 V7 a5 P
  1019. /* Input:                                                                                                                                */0 P) K1 v; E8 w+ k9 h: t8 @8 V0 n' G
  1020. /*                byte:                byte read                                                                                        */
    9 F# D) E, i% J/ a4 h" x
  1021. /*                cor_byte:        correct_byte that should be read                                        */7 J1 [: Y# f% l6 `# \" s9 ^
  1022. /*                                                                                                                                                */
    : _" h/ W9 s9 C% |: F" E
  1023. /* Returns:                                                                                                                                */
    # [" I$ L4 ~8 l
  1024. /*                Nothing                                                                                                                        */% a7 n3 d/ f) G2 [  i
  1025. /************************************************************************/
      A+ l: n9 x4 e  @+ s$ u
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    6 X& R/ I& g5 h# `$ N. W) v
  1027. {
    . P. b: A4 I# [! A9 w( S
  1028.         if (byte != cor_byte)
    * E8 n9 T/ g7 V- [( ^
  1029.         {% a3 x, C  U" |! r$ O
  1030.                 while(1); f" q. ]/ n) h) f# p2 n
  1031.                         /* add source code or statement for this file */( Q) W- x% U1 ]- B, q2 o( T: Y( v
  1032.                         /* to compile                                  */
    6 A! s/ R# `2 E0 S8 n7 [7 ]2 E
  1033.                         /* i.e. option: insert a display to view error on LED? */
    / n4 \! O3 _' ?% ]: R% w* j
  1034.                 % B+ Q  v: P9 g$ e0 C- f8 w
  1035.         }* J% b- y7 c4 W( Q5 {
  1036. }
    & ?8 \; I1 o$ W

  1037. 5 {$ H0 \0 w& M. y$ H0 B

  1038. , q4 @& \2 n! u3 t; a& [
  1039. int main()& Z3 C  a9 u0 S! v; [* O% G9 {& u+ W
  1040. {: Y7 t. ~$ {: C
  1041. 9 j9 {5 ^9 d: U2 g- ~: g8 |* c
  1042. return 0;
    ! {( w$ J" ^& N% f9 a/ e
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:$ ~' q1 e, E6 W5 X2 C
   main()3 v2 t' r" k  t
   里面怎么是空的呢?, O6 m0 K# u5 G' e2 O9 j$ i! Q
   发一份给我吧
  W9 p2 f, P+ _5 z+ |- ~7 Tmail:luyijun2005@hotmail.com0 T6 j2 V( r% @+ A
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
6 f# p8 Z  L/ p: s! f  m# ?
! @/ l; p; ^2 L4 Q; D: D" y: s7 v[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
! h+ U, {9 \* B7 XEC的代码在哪跑,你看DS的说明,每个EC都不同的。$ B: O" y) X/ l" M3 C/ X& K/ A: E& ]
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?' F& P3 |6 V. W5 S+ M
上面几个问题是你没看任何东西而白问。
) _$ O% x5 [0 ~  ]. R# U" l3 O3 C( h, I( a: B) a
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
* ?0 X: L0 H) J( F似乎要把SPI能support 到最大,这EC chip应该有好卖点7 S  y7 G8 v) g) U/ A5 p6 b
BIOS功能要不要强大,也就决定了SPI Flach的大小
8 V5 X. h" P1 d0 o& ?0 Q1 Y我是这么想的~让OEM去决定要挂多大!8 i% c- S1 ?5 a: W
如果我司有BIOS工程师就好了~哈
* F- }# h; l& HWPCE775应该算很新的东西,来看它支持到多大?! T: L( l5 p, o' b+ Q* w) s
$ w1 J9 ?% U; b! u( E' X0 ]
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte3 u% f! b+ o( d* Y6 b, Y4 U
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
8 x' d# X9 |/ [# s+ ^/ R2 ^7 H, Q" h
这份driver收下~希望以后有用到
) F5 N( h+ q8 q) A9 e谢谢bini大大
+ u/ i7 Y6 w5 T; F5 i0 g
$ T6 b& A3 y% D很新很新的新手,如有错误请指正 (准备看第二家的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 l. B8 T6 {1 M' u3 D. L{
% V- D, M" u2 F4 X7 o4 _+ M        unsigned char temp = 0;
* X$ G( Y4 W  [* ]  r        CE_Low();4 g- Q0 w! Z. h5 }1 i
    while (temp == 0x00)        /* waste time until not busy */8 `6 J0 j1 C0 ?; P: s) z7 A& l
                temp = SO;
& a' q1 }. n6 [& P        CE_High();
; |# p! P, `) ?  J2 h0 n3 d}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
/ q6 z/ g: D& f( l  F4 H5 z- O. Y. j" x4 B{1 ^; y3 k" Q9 Q3 T; Z5 e3 F/ |
        " G7 c% p: o" {( d- c
        unsigned char i = 0;
; _/ H7 f$ y+ U* ]: i  H        for (i = 0; i < 8; i++)# \- Z! G* F# T
        {
+ Q: L% M9 X, w" I) w2 S; G' L                ! M* d+ ]0 y! H6 e2 }( B- r# {
                if ((out & 0x80) == 0x80)        /* check if MSB is high */$ k4 A+ c7 |+ b7 H9 i# T
                        SI = 1;
, p  j8 k# W, L6 m! O6 U6 m& n                else
7 j7 z( f. }' L  |. W                        SI = 0;                                /* if not, set to low */
) W2 _4 n) u6 o2 o2 p. ` 问              SCK = 1;                                /* toggle clock high */' Y* @+ T7 m* d- v: x  d& N; C
   题            out = (out << 1);                /* shift 1 place for next bit */5 y& N! n9 p6 n# H; C
                SCK = 0;                                /* toggle clock low */# X; }# q  Z3 g- v
        }
* x" Y/ P+ K$ `$ U5 ~$ q" x}. C6 q: B) c! S* r! S7 ~
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-4-24 22:38 , Processed in 0.046069 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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