找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54047|回复: 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: x/ f! C" H, r; p
  2. & p, \$ e) s' M( A1 s1 R8 M
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory- w5 I* a' g2 }% I6 A- q; O6 T2 F
  4. . n1 v0 H; y( m$ |4 s- U
  5. November 4th, 2005, Rev. 1.0
      a; b7 O  w$ h) f3 Z6 G6 u
  6. / [. u: `( u: P# V
  7. ABOUT THE SOFTWARE
    % s) p) @, o+ Z& X) c7 Y' d
  8. This application note provides software driver examples for SST25VF080B,. N" l; f) b8 G4 |6 D: M. ]
  9. Serial Flash. Extensive comments are included in each routine to describe * z$ q' e4 g- k0 ]2 p6 M6 P
  10. the function of each routine.  The interface coding uses polling method ; ^/ N1 K: c+ E6 l
  11. rather than the SPI protocol to interface with these serial devices.  The
    & m& m3 j# i* G& x$ b+ R/ A
  12. functions are differentiated below in terms of the communication protocols/ X0 s5 W% c: `: o- e
  13. (uses Mode 0) and specific device operation instructions. This code has been
    0 Y3 |! {- M5 y
  14. designed to compile using the Keil compiler.
    ( M" @- h4 u& C% l# I* x
  15. 6 e+ x& l5 M& i7 x
  16. 1 N' z& s# T) A  |. h- {& I* z
  17. ABOUT THE SST25VF080B, g. L; n: A# c1 ]

  18. 3 U! E  j+ l7 c* Y) F, r% ^
  19. Companion product datasheets for the SST25VF080B should be reviewed in ' w8 r9 v% I5 U/ m
  20. conjunction with this application note for a complete understanding " k4 ]: ~, I& p8 _# [" _" B8 t6 `
  21. of the device.
    : M3 U5 R# p/ E9 U3 j, L: _- B
  22. : m$ |& x3 R" u, @' p
  23. 8 a1 P' |: y' y6 k3 ]! `( F( x
  24. Device Communication Protocol(pinout related) functions:9 l# _- x2 K! M7 {5 [

  25. ; {  ^3 p. M3 l) V/ x
  26. Functions                                    Function
    " J; j. j  p8 x
  27. ------------------------------------------------------------------
    2 f5 W2 V3 S* d, T
  28. init                                        Initializes clock to set up mode 0.- k, N* Y0 f8 T4 W3 i
  29. Send_Byte                                Sends one byte using SI pin to send and
    0 N& X+ G- C, N  _3 E# F; U( I
  30.                                                 shift out 1-bit per clock rising edge
    " x8 Q% H4 d9 S# D$ Q
  31. Get_Byte                                Receives one byte using SO pin to receive and shift 1 I7 t4 [$ F9 A% F5 J
  32.                                                 in 1-bit per clock falling edge
    8 M7 ^: j: v  ^( W7 ^
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    - ~% b$ m% T( ]
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high6 d2 {9 H% i3 [
  35. CE_Low                                        Clears Chip Enable of the serial flash to low& p& A8 n5 F( t9 N. ?
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    . O3 d% L$ L4 R$ I
  37. Unhold                                        Unholds the serial flash
    : v) |8 A0 G8 i  w- L- R8 i
  38. WP_Low                                        Clears WP pin to make serial flash write protected! D! {. t$ z& e8 f  @  Y0 m
  39. UnWP                                        Disables write protection pin
    ! I6 P6 E8 H; j  l

  40. ) T, y5 F1 c7 o3 @
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    4 h8 |, P; K7 I  }, ^
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your3 ]5 ^' Q  I! l+ ~( {
  43. software which should reflect your hardware interfaced.          6 D% E" T  V! P$ s

  44. ; m4 S: j; v6 M/ l6 d3 Q: N
  45. 7 R2 d: \" f9 O, q, Z
  46. Device Operation Instruction functions:
    1 j7 k# p# b2 B* N

  47. 5 d" L2 [* z9 [  k: j
  48. Functions                                    Function
    0 X5 w% I" \8 m  y
  49. ------------------------------------------------------------------. z( A$ f9 K4 R  X2 e% `8 w4 F7 c
  50. Read_Status_Register        Reads the status register of the serial flash+ R1 ^' _8 `, s% y3 p
  51. EWSR                                        Enables the Write Status Register
    " ?1 v8 [- E  K$ p( t* S
  52. WRSR                                        Performs a write to the status register
    % ?$ q0 e# L8 ~/ f+ Y+ H2 p2 G2 d4 h3 D
  53. WREN                                        Write enables the serial flash
    " h+ b8 I+ l. F  C; ?" N
  54. WRDI                                        Write disables the serial flash% g2 z+ T- O/ F
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming" e; T' r: b' [
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming/ I; [# W, [5 g9 L8 R. v
  57. Read_ID                                        Reads the manufacturer ID and device ID
    , R  F' u- d. |+ k7 J: g$ C; y$ E
  58. Jedec_ID_Read                        Reads the Jedec ID. y* u- H% ^4 v* J8 A
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)8 R8 }% @! C4 t/ }
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    + J" {' N; B: _; H3 v, j4 C
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)+ v7 A$ O; [2 |# n& A
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)& S7 I8 ~  Q% z  i
  63. Byte_Program                        Program one byte to the serial flash
    % c. H; `  b9 T' b6 g% |
  64. Auto_Add_IncA                        Initial Auto Address Increment process& Z; b1 Q6 m6 s# S% L0 g% v
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation+ @; D$ g) O1 b1 \6 s( s! u
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    $ s; V+ E0 p  @0 b
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY" w% ?! i8 C! F) y' l% O. y: ?
  68. Chip_Erase                                Erases entire serial flash: d( I( w/ o! |
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    9 F1 t4 y3 a+ d1 n
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    ! r' L9 T) v1 t6 k
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash2 p0 M) _) x# ~2 f% c
  72. Wait_Busy                                Polls status register until busy bit is low  T* C# N/ Z& @5 D9 ~
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    3 x2 l6 @4 b1 d+ C
  74. WREN_Check                                Checks to see if WEL is set$ u, Q) A. C- u, A3 }" r! K
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set7 i/ |7 Z2 f1 ?, _

  76. 2 q0 B$ x; k; \' p" K( |

  77. 4 e+ _; U% ~; c/ b/ O; P

  78. # U+ W) X( O) q# {, G+ n
  79.                                                                      0 g) B( K2 u- K* g
  80. "C" LANGUAGE DRIVERS % q1 T! m( v3 f$ z2 }9 J
  81. 9 q7 b4 V. r. M! U$ z! V; a$ t2 _
  82. /********************************************************************/9 N, N* ^9 s8 I4 [
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */: o( u) _; n6 h
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */$ {  m# `3 O: Q5 s8 I
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */' ^" {% d5 C  g  ^; [- J! K3 t6 B
  86. /*                                                                  */  _. T. l0 T8 ~6 {; H) A2 L( I
  87. /* Revision 1.0, November 4th, 2005                                                                          */   8 Y4 m) @. \. }# G1 P
  88. /*                                                                  */
    & b( {1 v: H! v: y+ V; G! B+ _" l0 X
  89. /*                                                                                                                                        */
    " {" f$ ~4 i+ j1 b. _3 U4 v1 Z- k
  90. /********************************************************************/
    ! d' C' j5 @, f; z4 c% z  E, T* _+ A
  91. ( b5 u. [5 `7 R' k* L
  92. #include <stdio.h>5 B8 o9 B: E& x2 D0 T& m. f: M" z
  93. #include <stdlib.h>
    6 E$ i# n& l+ F" H
  94. - w7 C( D, w; G
  95. /* Function Prototypes */4 [9 ^; G: @9 |- b6 S1 `' \
  96. " m" U$ R* r0 C. N) y( }
  97. void init();
    2 d- }; Z; R- h9 G) O
  98. void Send_Byte(unsigned char out);. [6 Q! {. `% v( `" F
  99. unsigned char Get_Byte();
      a/ P) [$ U6 }
  100. void Poll_SO();
      T5 j' f5 j2 j3 l0 T8 O# ]
  101. void CE_High();
    , O/ p0 F9 T. J& q  g
  102. void CE_Low();/ ]. a5 o# Y5 l
  103. void Hold_Low();
    & v8 l1 z; b( v; B7 @5 o2 ~
  104. void Unhold();
    ! @5 U* k( ^% H. `
  105. void WP_Low();
    * {" e7 C/ `/ k/ p! k; x
  106. void UnWP();2 @  Z% K4 x* N& Z/ J9 a' k9 Y% Z
  107. unsigned char Read_Status_Register();
    % N$ b$ g% W) R: N& V$ d9 K5 {
  108. void EWSR();
    ! T4 c& s* r. e) L8 ]
  109. void WRSR(byte);
    + F! z. h: G5 a6 S
  110. void WREN();
    7 m- C- ?+ b5 @& F4 b. C
  111. void WRDI();8 m, }# y. D, u. @) U" M. o& N
  112. void EBSY();. K  \6 Z' K$ o2 x" J5 o6 j$ t
  113. void DBSY();% z6 c9 }/ u- i$ U3 x5 _# E
  114. unsigned char Read_ID(ID_addr);) y! ?2 l" s; t! m& j0 e1 J% W
  115. unsigned long Jedec_ID_Read();
    3 e8 X1 Q8 I  D+ }" y! z+ f
  116. unsigned char Read(unsigned long Dst);
    8 [# e; ]! a& b2 v$ a: L% \
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    7 Q7 b$ Z9 f. o$ f8 o. W' d( u
  118. unsigned char HighSpeed_Read(unsigned long Dst); 7 B5 L8 a0 E" d  P, S
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);3 m( x5 \( L6 C4 D6 D) ?$ ?
  120. void Byte_Program(unsigned long Dst, unsigned char byte);5 Z. i3 h3 n. t) G* t. N% F4 X
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    8 I$ N$ R5 V* `. V1 o7 a3 r: I& X  B' a2 G
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    0 G( ]9 G5 Y* \! G. j
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    , A1 m. C/ D5 c, B
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    % I* E, e4 m4 I# o  O/ T" }" ]5 q. Y
  125. void Chip_Erase();8 F0 ^7 O  s$ |" K2 I" G" C
  126. void Sector_Erase(unsigned long Dst);) u5 U2 l7 p3 D7 q1 R' d0 _
  127. void Block_Erase_32K(unsigned long Dst);
    . `" |% u# K$ b
  128. void Block_Erase_64K(unsigned long Dst);3 F+ `1 k7 q6 \. g/ y# p
  129. void Wait_Busy();
    # K5 {2 s3 U. F8 {7 V
  130. void Wait_Busy_AAI();
    5 R6 y- J% i8 B5 q9 p) |
  131. void WREN_Check();
    ) [% x' S$ |' ^7 \* D1 y2 [
  132. void WREN_AAI_Check();
    - w' L4 m5 h& }2 @

  133. & M, B& I7 W' k8 ]
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    7 n: d# f2 R( U

  135. 2 z' y6 o- Q9 A2 [7 a. |
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    ) Q# A. e6 _& s1 Z
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    4 r4 X: P) L) _& Z4 n7 j" K

  138. ( G$ C4 P( Z; o3 q2 X. w) `
  139. /************************************************************************/
    6 H+ _9 S( ]) v3 o# ^0 c6 o/ ~
  140. /* PROCEDURE: init                                                                                                                */, t) |/ t; |3 L' a! V0 q
  141. /*                                                                                                                                                */' {: Z" k. c" [2 |. b5 G
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    6 V: d+ o" f7 J& P# z
  143. /* setting up mode 0.                                                                                                        */
    : T. {  p' [/ u* D
  144. /*                                                                                                                                                */
    / Y+ w4 b+ N6 K5 G, C
  145. /* Input:                                                                                                                                */
    4 e2 D9 p1 r0 A' ~  u  c
  146. /*                None                                                                                                                        */8 d% ?9 |; ~0 x' B+ V1 M& Y
  147. /*                                                                                                                                                */4 _" Z$ I; v. K: p3 Y$ H- u* n
  148. /* Output:                                                                                                                                */+ O  V9 U/ G  i. j% V, n
  149. /*                SCK                                                                                                                                */
    ( h/ O) n9 _$ I1 w
  150. /************************************************************************// }0 s% J/ y+ s) K: c
  151. void init()' K/ M  q; G7 U
  152. {
    ! X! {2 ]7 A" M0 e: F0 \8 z4 O
  153.         SCK = 0;        /* set clock to low initial state */: z/ {+ P' d) E- H% b
  154. }
    * i2 Z' ^7 \9 p2 r7 b( L# ~

  155. 6 O* h1 C8 t/ e# N
  156. /************************************************************************/
    % |7 s  @6 J! N7 F! p7 K3 ?
  157. /* PROCEDURE: Send_Byte                                                                                                        */. }9 s. ]4 h& H# r5 }& S
  158. /*                                                                                                                                                */
    ) s3 {0 A; N) q6 g0 X
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    / d: l& J1 ~$ i1 |) o( g2 M4 ]
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    " B/ s1 Z/ D# t6 T1 j
  161. /*                                                                                                                                                */
    1 {5 ]) n( v6 f) T- t
  162. /* Input:                                                                                                                                */- ]& y) Y5 ]9 Z( Z6 [8 C' e
  163. /*                out                                                                                                                                */, N, l! n6 X1 {7 i
  164. /*                                                                                                                                                */
    : C2 i4 Q: \; {
  165. /* Output:                                                                                                                                */
    # J, |. S: U& I. }, }! M3 D) V
  166. /*                SI                                                                                                                                */
    , K5 A! x! m: j% n* x
  167. /************************************************************************/
    " T; N& N6 e9 c, F' W( f; g* c
  168. void Send_Byte(unsigned char out)" t5 \& S7 y8 |% K3 u( o# J1 e
  169. {
    9 T9 T% q- [4 |8 p  Y2 c+ ?6 b
  170.         ' R6 ]9 T+ S( v+ b5 C
  171.         unsigned char i = 0;0 R+ p' R* ?- [+ L$ E
  172.         for (i = 0; i < 8; i++)9 \, u# f# a# p1 |+ r6 K5 G/ V
  173.         {3 e  I$ a8 z( {7 e3 V# P
  174.                 0 |4 s$ ]; K2 q9 A
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
      B9 e% Z! I3 B4 n6 t
  176.                         SI = 1;! n+ R4 M, o. @8 b
  177.                 else. K4 |6 t* n. K) G! t
  178.                         SI = 0;                                /* if not, set to low */! \7 Q  g0 |9 v& B
  179.                 SCK = 1;                                /* toggle clock high */# }2 l) w( Z/ p1 F+ ]6 E
  180.                 out = (out << 1);                /* shift 1 place for next bit */+ [+ j, P- N8 p2 U2 P$ J3 `
  181.                 SCK = 0;                                /* toggle clock low */2 Y) ], f0 t/ j+ p
  182.         }4 L- p9 x: ^5 ]3 H" y# H
  183. }, s) o$ _# i0 o, l. g) p3 E
  184. & Q: t, K1 Z* X/ ?7 R" @* C- v/ T" O, \
  185. /************************************************************************/$ j' Q" g% O6 C3 q& k7 p
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    / x. v+ w! Y3 z0 X& X# `8 B8 z
  187. /*                                                                                                                                                */6 b- o% O8 J* ~3 K& a! w
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    ) z$ D3 Q+ z! j& m4 i- ?1 y
  189. /* edge on the SO pin(LSB 1st).                                                                                        */6 ]$ N) a. R0 C& @* m/ R$ X
  190. /*                                                                                                                                                */8 r. i6 `6 s7 M: w
  191. /* Input:                                                                                                                                */
    . O* b, b; W8 Y0 H1 t
  192. /*                SO                                                                                                                                */
    * o6 K0 t7 S! |, H- o3 j  a
  193. /*                                                                                                                                                */. v8 ]% ]( r% @$ j
  194. /* Output:                                                                                                                                */
    # {0 _7 l5 I/ J' N, y
  195. /*                None                                                                                                                        */5 n, x2 t8 a& [: S' d$ j
  196. /************************************************************************/0 Q9 ~) E4 L1 d( L$ C+ L
  197. unsigned char Get_Byte()( X* B6 p  r  K  h
  198. {% H/ T+ q( d; j" }9 }
  199.         unsigned char i = 0, in = 0, temp = 0;
    , W% i, A$ U0 ]- \% p
  200.         for (i = 0; i < 8; i++)
    1 S+ Z' R9 e# t1 E
  201.         {- t4 j# R/ b) E& Z* P4 q" d7 a+ Z
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */3 `5 p; U* `0 x, i6 {
  203.                 temp = SO;                        /* save input */
    ' j4 r  K% X( a1 F/ x/ ^
  204.                 SCK = 1;                        /* toggle clock high */
    + Y( O- n6 e3 R
  205.                 if (temp == 1)                        /* check to see if bit is high */, E: S) U+ J4 E
  206.                         in = in | 0x01;                /* if high, make bit high */: a$ I9 I! c3 |3 h( f9 |

  207. . r3 v( t8 l5 {, `
  208.                 SCK = 0;                        /* toggle clock low */
    ; X% @6 d3 |( b1 e% @

  209. $ h4 z+ j, h0 u7 m4 V
  210.         }5 p* ~' p$ ^3 ^
  211.         return in;
    . r8 z6 J6 F" g
  212. }
    9 d- X8 b8 p% ?! L( `; C
  213. 3 B& B, g$ [$ l& l7 ~
  214. /************************************************************************/
    9 s  T( K) s' u
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    3 ]  ~7 t, M( V+ ?
  216. /*                                                                                                                                                */% r+ K; H/ D/ P2 h
  217. /* This procedure polls for the SO line during AAI programming                  */  E, i, h7 ?' J- K
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    & |- V" j) W7 ]4 L  S3 U
  219. /* is completed                                                                                                                        */! R& T8 p  o/ k
  220. /*                                                                                                                                                */" _( p+ X" \1 `2 D: r2 e9 {2 X0 L! v7 n
  221. /* Input:                                                                                                                                */
    1 K* A) R$ I3 W3 n; v; R" p9 G5 @4 t
  222. /*                SO                                                                                                                                */
    " J. f  f$ e8 C: O4 \
  223. /*                                                                                                                                                */
    : t1 }# Y5 f6 e: W
  224. /* Output:                                                                                                                                */
    0 E4 V) Q0 u% d- [. B9 U/ X5 I
  225. /*                None                                                                                                                        */
    % u2 ]* B' p6 K0 U) {  q+ n
  226. /************************************************************************/
    0 K9 O: w0 I( |. A+ E6 Y: T
  227. void Poll_SO()
    6 F5 {9 I4 K, s
  228. {
    * _$ c# u0 z+ C3 L; I) \; S" v/ P
  229.         unsigned char temp = 0;
    + Q& Q  k/ j- x) \) U
  230.         CE_Low();0 i: ~8 N  n$ s$ d
  231.     while (temp == 0x00)        /* waste time until not busy */7 J$ r1 O0 \6 V) I# r( D4 X% p
  232.                 temp = SO;
    % A" v& E! `9 b6 J2 J
  233.         CE_High();) F$ f! J( h6 V5 T5 Z
  234. }8 n  n4 V  V' I6 V  n% `
  235. 9 K7 Y' o& }4 ^, Q8 J
  236. /************************************************************************/
    ) Z) i3 z0 z0 L9 j; H8 O: }7 D
  237. /* PROCEDURE: CE_High                                                                                                        */' {) [5 }8 z: Z! @4 O. z
  238. /*                                                                                                                                                */' m. ?. h) }* g4 v( `; R
  239. /* This procedure set CE = High.                                                                                */
    1 l( l0 n8 z# |0 w( F" K8 K: Q2 }
  240. /*                                                                                                                                                */7 A* g7 {, h( |  u0 H+ |* }: M
  241. /* Input:                                                                                                                                */
    ! h& H. f$ v0 O1 p  p/ e
  242. /*                None                                                                                                                        */# k' I. E6 x, x8 z
  243. /*                                                                                                                                                */
    % _1 w9 ~$ f- H! G
  244. /* Output:                                                                                                                                */# P/ @: B$ a& W6 [
  245. /*                CE                                                                                                                                */% L) h4 z0 |8 e4 F9 x2 ?
  246. /*                                                                                                                                                */
    5 }$ J$ y9 ?% B! ?1 j( M. q7 e
  247. /************************************************************************/
    # f' `( C2 C4 c, X
  248. void CE_High() $ i, j/ V% X. C* b
  249. {
    ) t# q, Q( c( B, L$ C( D
  250.         CE = 1;                                /* set CE high */
    1 S7 N3 P; `, J6 y
  251. }
      z7 C% \" E6 G) ^7 o' D
  252. 0 [# \5 Z  E1 U2 J, b
  253. /************************************************************************/
    9 Q3 S/ j6 K, V4 u  M) J
  254. /* PROCEDURE: CE_Low                                                                                                        */8 R( c$ X1 N1 i+ y. t: M/ [' L! _
  255. /*                                                                                                                                                */1 W2 o! \& i: ?4 U9 J5 V+ ~
  256. /* This procedure drives the CE of the device to low.                                          */' Q/ t. u/ u2 H( a2 I8 t
  257. /*                                                                                                                                                */
    : H2 B) |% D' ]. e) Q7 x  r
  258. /* Input:                                                                                                                                */3 `  S6 i  K/ e* A' @/ H/ T# W5 Q0 H
  259. /*                None                                                                                                                        */
    , j* t$ Z% l1 x0 a! F4 v) D
  260. /*                                                                                                                                                */
    # M" e& g# D! D, t! d" T
  261. /* Output:                                                                                                                                */& f3 |8 u* ~& [
  262. /*                CE                                                                                                                                */+ w9 s2 I( v2 @8 t& b3 i, |) l
  263. /*                                                                                                                                                */
    $ _( o$ F" D6 n: K$ x' x7 O
  264. /************************************************************************/& V! z* E% r2 A; ]# _
  265. void CE_Low() $ f$ Z: t( Q' N. q! F5 H
  266. {       
    ' l3 R1 G# W9 L7 @7 u6 h: ~1 S0 D
  267.         CE = 0;                                /* clear CE low */
      f* U0 [7 E; B3 M
  268. }
    * x( }2 f6 F) |! m
  269. $ q! ~, K& |! E  c# [
  270. /************************************************************************/: o0 b( u; k, P# o
  271. /* PROCEDURE: Hold()                                                                                                        */( A! g9 ^* h; V! O# G3 I
  272. /*                                                                                                                                                */
    % E4 h* b2 o9 m( N7 v/ x& f
  273. /* This procedure clears the Hold pin to low.                                                        */
    7 Y5 @) w/ x7 i$ f
  274. /*                                                                                                                                                */3 H" D+ H+ K% i% I, g
  275. /* Input:                                                                                                                                */; V8 U# N1 i9 a
  276. /*                None                                                                                                                        */! F6 y% y. s) Q! }% s  h5 n+ }
  277. /*                                                                                                                                                */
    4 t. ^: |4 [. N) e9 |$ _
  278. /* Output:                                                                                                                                */
    & V/ }0 I9 r% |
  279. /*                Hold                                                                                                                        */
    + b4 K$ i" j) Y# d6 V( s
  280. /************************************************************************/4 ]6 @' z' k: H2 _% G8 r
  281. void Hold_Low()
    9 h+ H9 J9 D" }4 _% ~) P: o0 }6 _! i
  282. {
    ) _0 F- j4 a9 \" E
  283.         Hold = 0;                        /* clear Hold pin */! B, }: I" y; ^, \
  284. }- r( K4 G* G/ o+ ~1 _5 y+ x

  285. 1 I- Y8 U# j; c2 l3 g8 o
  286. /************************************************************************/& _' j1 C. z0 s. k- @
  287. /* PROCEDURE: Unhold()                                                                                                        */
    6 n/ A% o1 _; s- ~- _
  288. /*                                                                                                                                                */
    ) N2 X- X7 i$ ]4 X
  289. /* This procedure sets the Hold pin to high.                                                        */* d% e# B+ R* H: h! D' e1 [: @
  290. /*                                                                                                                                                */9 M  R& M! B! B9 {
  291. /* Input:                                                                                                                                */
    2 R. x# f! M. v6 G% L# X- u4 p
  292. /*                None                                                                                                                        */3 v; A  f( x6 a* z: O  b5 O- f! b
  293. /*                                                                                                                                                */
    6 q6 ~. W7 I$ E  w( k
  294. /* Output:                                                                                                                                */% i- V  p$ j# t& V; M3 ?
  295. /*                Hold                                                                                                                        */
    ; I3 d: D' ^) S5 ~' a/ P: T/ E
  296. /************************************************************************/. v2 q. d" p9 r  Y6 ^+ D$ T
  297. void Unhold()$ P6 {9 ^; v+ I  m7 \
  298. {
    & X2 w; H4 Y! b4 T8 U8 ^, G  ?
  299.         Hold = 1;                        /* set Hold pin */5 T$ Z& m5 a, \, k3 D% v
  300. }
      ]7 l1 Q1 H7 {/ x$ u1 _: {- [
  301. ) E  b! K% h4 D0 T9 I5 I: O( _  D6 G
  302. /************************************************************************/- t/ c' J9 b$ n% \
  303. /* PROCEDURE: WP()                                                                                                                */
    4 W& N' R; c) J4 y; I
  304. /*                                                                                                                                                */
    , e% M9 i3 ?! w
  305. /* This procedure clears the WP pin to low.                                                                */
    2 {( o  `  K$ _7 O4 w+ w- e
  306. /*                                                                                                                                                */
    % Z8 R9 i6 t0 D
  307. /* Input:                                                                                                                                */
    : J7 z" X& \* O+ ]# S6 b4 K
  308. /*                None                                                                                                                        */) r4 R2 z2 ~  ?: t4 ~: r5 T% }0 V" P
  309. /*                                                                                                                                                */6 [  w) \1 k8 C+ W9 a4 f$ R" S
  310. /* Output:                                                                                                                                */$ s' y& h, A, K5 z& n  \0 w# |
  311. /*                WP                                                                                                                                */5 O4 m' f& v6 p- T
  312. /************************************************************************/
    ; w3 z- p$ I  k  ]! [# M
  313. void WP_Low()7 I+ U1 B+ E3 K! i: e$ \8 Q, C
  314. {8 M7 b. B" `2 V; _- N$ N/ V( }
  315.         WP = 0;                                /* clear WP pin */
    2 @4 n/ y1 u/ Y: O, ?; i! j
  316. }8 @6 G5 J, P% }9 N" b1 C% V# _& {( _+ O
  317. ; [% r/ }( p: t1 h  }* G, Q8 ~
  318. /************************************************************************/
    . h* l5 b. z2 O1 l' E* H
  319. /* PROCEDURE: UnWP()                                                                                                        */5 i. W# I1 m& t8 c. Z* |
  320. /*                                                                                                                                                */
    % m% ]  s3 i/ S
  321. /* This procedure sets the WP pin to high.                                                                */
    5 f  X% ~  E3 Z9 ?0 e
  322. /*                                                                                                                                                */2 b- e& o' ]5 B. e8 k5 R
  323. /* Input:                                                                                                                                */7 c; @+ g' a$ u/ M# b/ ]
  324. /*                None                                                                                                                        */
    2 u6 I  |* S# c: [4 j
  325. /*                                                                                                                                                */
    7 l* E8 L* y2 ~5 n
  326. /* Output:                                                                                                                                */: r  {! X# @- k6 B& r0 M2 ]2 Q1 P
  327. /*                WP                                                                                                                                */. u- l8 j% u! {; G% c: [3 T
  328. /************************************************************************/- a( z5 u1 V$ U$ P
  329. void UnWP()
      C) C3 `4 |; Y+ j; u0 X8 ]% M
  330. {1 L" Z) ~, a; h4 R8 v; t4 v& W
  331.         WP = 1;                                /* set WP pin */3 s4 h9 J2 a7 M; t* N+ m8 n! s
  332. }
    / G& @1 K) U# v7 m" P
  333. 7 N/ C/ N+ u; F+ |8 M, N4 ~
  334. /************************************************************************/" m2 n& B) E3 I3 f) i
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    * \8 a0 b, h) X0 V' B  f+ N
  336. /*                                                                                                                                                */8 W9 b  P  M( B( u- i5 g
  337. /* This procedure read the status register and returns the byte.                */& g  R0 C: p  R( @" k# o
  338. /*                                                                                                                                                */7 I. s( N- D! o. @+ _* _! c
  339. /* Input:                                                                                                                                */
    ' Z: Y& i* J( V3 c* z
  340. /*                None                                                                                                                        */# S- ~- B0 C0 {: e- x& N' w4 r
  341. /*                                                                                                                                                */
    * A* u9 h6 L% N7 }$ k8 x
  342. /* Returns:                                                                                                                                */3 \$ m( F% Y4 F! N4 x1 |
  343. /*                byte                                                                                                                        */0 M2 Y6 C3 N. O* N+ f" b1 F
  344. /************************************************************************/( V+ x6 b2 ?( N" \, R( I) h
  345. unsigned char Read_Status_Register()
    9 C, D7 B; R6 X. L# R
  346. {3 {0 f" |) A  k& B) c# y
  347.         unsigned char byte = 0;
    , P$ S0 \  O1 r+ w
  348.         CE_Low();                                /* enable device */3 K8 Y4 d0 j7 k5 `2 z$ S& z+ N
  349.         Send_Byte(0x05);                /* send RDSR command */9 Y* W  V/ h: Q7 q4 G  q
  350.         byte = Get_Byte();                /* receive byte */
    6 j0 t7 p( [! i1 x9 A' p
  351.         CE_High();                                /* disable device */3 q0 U" ~& I' W: V$ u: a
  352.         return byte;
    ) w5 o' v" C4 T/ J: M
  353. }
    % i  Z  p0 ^3 t2 x

  354. ( \7 s5 _) E! F' i# Z  y. b
  355. /************************************************************************/1 J3 x! g0 N* s* V
  356. /* PROCEDURE: EWSR                                                                                                                */  u7 H/ a0 F6 d5 S
  357. /*                                                                                                                                                */
    * `7 C9 C) h+ x1 W7 R
  358. /* This procedure Enables Write Status Register.                                                  */, w: ~4 q( r1 X3 {
  359. /*                                                                                                                                                */
    / v- p: n6 M* }! q  z. i4 v2 R
  360. /* Input:                                                                                                                                */
    6 T, H, T8 P1 U- m; z9 b5 J
  361. /*                None                                                                                                                        */: \' K/ I+ |8 N- j; k' [5 u
  362. /*                                                                                                                                                */
    ; X3 O, ]; l! f  M$ W  s
  363. /* Returns:                                                                                                                                */
    % E- F% H4 ?7 g) H. T+ {
  364. /*                Nothing                                                                                                                        */. A. }# N2 Q2 R, t3 D
  365. /************************************************************************/8 Q0 T* L4 o/ @4 j* _* E
  366. void EWSR()1 g% P! B8 u! G
  367. {
    - J0 u$ `* L  ^1 I: ?$ G; }& q
  368.         CE_Low();                                /* enable device */( R# i. \" \1 Q4 d; D( I4 n9 V
  369.         Send_Byte(0x50);                /* enable writing to the status register */" I- J# S8 t( y! P$ `6 q! ]8 }- e
  370.         CE_High();                                /* disable device */, H. U% }! y0 D  v
  371. }, g" \+ Q/ r- }8 |7 j$ C
  372. 4 `& C: D& K8 I" G) j/ h
  373. /************************************************************************/  O( y, m: g  V2 v  ~- ~
  374. /* PROCEDURE: WRSR                                                                                                                */
    % T; ~- x3 @; ^, m$ C+ u" o3 p, {
  375. /*                                                                                                                                                */7 H! b: K- }* \  G  k% u( ~0 ]
  376. /* This procedure writes a byte to the Status Register.                                        */
    ; I+ }- m4 [2 u# G) e
  377. /*                                                                                                                                                */8 ~+ O) l) K; h/ y
  378. /* Input:                                                                                                                                */
    8 F8 ]9 `/ Y$ V) w' `' s# N% j
  379. /*                byte                                                                                                                        */" M- L* K4 T0 W, E4 j% g8 L4 `
  380. /*                                                                                                                                                */7 [! U' A: V( U" u, {
  381. /* Returns:                                                                                                                                */! Q# ^1 |7 [7 ^* s( U- M0 U8 P
  382. /*                Nothing                                                                                                                        */' z5 J! M+ f- a- G! T
  383. /************************************************************************/* [  x  Y8 L6 `6 f  D- P
  384. void WRSR(byte)8 Y0 N, }9 v! d. {1 A
  385. {. I  G# D: N$ E: s
  386.         CE_Low();                                /* enable device */% h# @( r6 G2 d" E5 N! z2 s
  387.         Send_Byte(0x01);                /* select write to status register */, {9 \! ]! y: U
  388.         Send_Byte(byte);                /* data that will change the status of BPx 0 T$ B+ s1 _+ m" R" ^* }9 v
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */0 h9 g5 E3 s; n  G# `$ t6 |5 a
  390.         CE_High();                                /* disable the device */
    1 q0 w" S  a: Q4 V! Y& L0 F
  391. }
    " S% p" h- w; Z
  392. ; a; `! m; @" ~* f
  393. /************************************************************************/
    # X/ o6 H  [$ w& v" Z7 B* k) i6 }
  394. /* PROCEDURE: WREN                                                                                                                */  ^; O( @) T+ u
  395. /*                                                                                                                                                */3 P& R4 z' }; |# z1 r: m/ I8 y
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    % f/ Q/ x4 ~# x, W$ {
  397. /* to Enables Write Status Register.                                                                        */
    # B" F- _* }% e& N, ~$ v
  398. /*                                                                                                                                                */
    9 T0 H  N' f/ p: O
  399. /* Input:                                                                                                                                */
    - W* K& Y/ H! a/ |( A. A
  400. /*                None                                                                                                                        */  z4 l+ ?8 k; v" s( w8 Q
  401. /*                                                                                                                                                */9 m; Y* ^7 r+ [( h8 J. p! h
  402. /* Returns:                                                                                                                                */. L+ \4 d3 N) T" n. d* G; m
  403. /*                Nothing                                                                                                                        */' `2 V, e5 Q) G' o: @
  404. /************************************************************************/
    9 M- _- A8 {' P0 H5 }1 ]
  405. void WREN()8 j8 n( q: e& n: W2 Z6 ?* b+ R
  406. {
    2 N) e) `! n6 n% |6 A
  407.         CE_Low();                                /* enable device */
    ' t  e5 J- A6 G
  408.         Send_Byte(0x06);                /* send WREN command */' J! i& x3 P! I  c
  409.         CE_High();                                /* disable device */
    . ?- X: N; x, B
  410. }
    : X5 `- L  r; X$ |

  411. $ y& C: o9 B# m- b
  412. /************************************************************************/
    1 _' @  T: n2 X) y( L
  413. /* PROCEDURE: WRDI                                                                                                                */
    " I7 p/ W4 B& K% G
  414. /*                                                                                                                                                */
    1 [; J# s/ D) m% m7 _
  415. /* This procedure disables the Write Enable Latch.                                                */& ?; S1 w+ m% d
  416. /*                                                                                                                                                */: Z: ~) E/ C& Z8 \
  417. /* Input:                                                                                                                                */
    9 |/ t6 R; L5 B0 B
  418. /*                None                                                                                                                        */
    0 a$ l+ [" m: g! z2 j9 X2 @* S
  419. /*                                                                                                                                                */; p% f9 |& `# I
  420. /* Returns:                                                                                                                                */$ B$ {# U1 b8 m2 w; ~# m
  421. /*                Nothing                                                                                                                        */: l" A+ T( Y# R; e2 g
  422. /************************************************************************/
    $ K- ?) |8 x( c6 h
  423. void WRDI()
    ) z3 i% ^6 W7 c
  424. {- x* i% J7 @/ a2 S, K
  425.         CE_Low();                                /* enable device */
    . {3 ~  Y. b* G0 W# i, x( P  D& R4 {
  426.         Send_Byte(0x04);                /* send WRDI command */8 N, u* i  {! a
  427.         CE_High();                                /* disable device *// V- Z& E" Q% J8 S! \) h1 S
  428. }
    2 s' k) |; b) B4 `$ U
  429. $ ^; {% c* U. E4 H& ~5 P7 |7 ]) M  @
  430. /************************************************************************/
    2 i9 \- u* I/ b8 X$ t. `* o, B
  431. /* PROCEDURE: EBSY                                                                                                                */* Z' W- r$ c5 C3 A+ {
  432. /*                                                                                                                                                */' X; a5 s; r( p: V% @6 z" x
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    ( @4 I( D; h" q2 Q1 O
  434. /* programming.                                                                                                                        */8 r* Y6 \8 {" P& A2 j
  435. /*                                                                                                                                                */
    % y" \$ b9 J# j9 L
  436. /* Input:                                                                                                                                */
    & i) Y, j% N0 c) A* S
  437. /*                None                                                                                                                        */
    : V- I6 C5 Z5 y  s
  438. /*                                                                                                                                                */7 J4 a% d0 E2 v) _
  439. /* Returns:                                                                                                                                */
    . P, _+ R3 T( h0 }( H( x" [. L1 Q. C+ U, ?
  440. /*                Nothing                                                                                                                        */
    $ l- @( b/ S3 @/ {- C* q
  441. /************************************************************************/* w8 f7 g8 q  b2 _
  442. void EBSY()
    : e$ ~) c9 ^: {$ ^3 B+ w9 B
  443. {# ~0 Z3 ?$ J/ S- [0 @- x5 f* A3 I
  444.         CE_Low();                                /* enable device */
    ' l- t9 C5 @) @; a2 d$ Z+ D
  445.         Send_Byte(0x70);                /* send EBSY command */, K$ R. R5 Y% a& a0 M; S: ?
  446.         CE_High();                                /* disable device */
    + s8 V) a% v. H& j: O0 Q
  447. }& Y' u" M8 Q/ n, }
  448. & _+ K/ \7 K) a
  449. /************************************************************************/
    + `9 ~8 A7 Z- T
  450. /* PROCEDURE: DBSY                                                                                                                */
    0 g& \% I: w* p5 C5 ?
  451. /*                                                                                                                                                */
    ; \0 v" r  w/ g; a  d/ n& Q8 ~
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */3 j- k4 u: T1 U$ [
  453. /* programming.                                                                                                                        */' A+ ]' Y; R" f
  454. /*                                                                                                                                                */  f  K& u! s/ L. Y/ ?- U2 j# A1 |! Q
  455. /* Input:                                                                                                                                *// H1 ]2 o+ R7 [& w3 c& c( i
  456. /*                None                                                                                                                        */# \( n8 x2 y& r
  457. /*                                                                                                                                                */3 `3 }: b" O- c# @5 x
  458. /* Returns:                                                                                                                                */
    5 H0 |$ p/ O/ i- [! g
  459. /*                Nothing                                                                                                                        */
    + b' j; ]3 l: [- g3 B' }4 j; W
  460. /************************************************************************/2 s6 P: p8 X0 D2 u
  461. void DBSY()  c2 r5 U/ e; I/ G; l) L0 I! h
  462. {
    ! L: E( E% f% K# q. g
  463.         CE_Low();                                /* enable device */! `3 z, k, K+ x" R8 k7 A3 F7 P& t" f
  464.         Send_Byte(0x80);                /* send DBSY command */
    3 Q" K- S/ R6 f. M
  465.         CE_High();                                /* disable device */' f8 Y0 h3 M4 |9 u8 T' ]
  466. }
    5 r" o, x; I% @; S2 c, g

  467. $ h# Y% i; ~: W. Q: o" s- ]
  468. /************************************************************************/
    # c, ]% J# u& m
  469. /* PROCEDURE: Read_ID                                                                                                        */
    6 Q' [5 H" P! W) p3 |/ P" [' r! A  @1 |: S
  470. /*                                                                                                                                                */
    ) t6 p1 x% _/ \! Q1 R9 q8 o2 O
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    ! z0 d- u: c" h  H6 W' Q
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    1 b; r3 g1 p* a/ W' H
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    , |) }% F4 |; a& l
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    4 C; C* K) S* c3 j6 T' z
  475. /* first.  Please see the product datasheet for details.  Returns ID in */) ?5 ~# M$ }0 R5 b0 s# h& m+ P
  476. /* variable byte.                                                                                                                */0 ]" E% }' ]& D8 G4 D; ]" f. }
  477. /*                                                                                                                                                */- Z( V( U2 z: }
  478. /* Input:                                                                                                                                */
    1 O' u, _$ D, z/ ?' U# N
  479. /*                ID_addr                                                                                                                        */
      b7 o& `9 S) k3 Q# ]
  480. /*                                                                                                                                                */
    ' P) ]2 b5 \' W. o6 z* M
  481. /* Returns:                                                                                                                                */
    , U9 P& k9 D9 n( M7 q
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */6 f% |. [% T) D
  483. /*                                                                                                                                                */
    # j" b+ d6 @/ l) |: w
  484. /************************************************************************/* J9 n& T9 m% M) e% _
  485. unsigned char Read_ID(ID_addr)
    4 V% p* `* z4 M$ D
  486. {
    ( b! I: z. p5 Y, v; L4 W
  487.         unsigned char byte;: @; d7 A8 f% h6 }! |0 G. t+ a
  488.         CE_Low();                                /* enable device */
    8 l3 P0 A# U" b& C; d
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    " o2 N, y; z% j" ]- q+ x& _
  490.     Send_Byte(0x00);                /* send address */
    7 ^+ S: {9 y' X4 L3 k: }7 ?" x
  491.         Send_Byte(0x00);                /* send address */, J( ^1 v. M* x$ M" G
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */# M6 E$ ?* Y* K- R" g' w2 Q4 X
  493.         byte = Get_Byte();                /* receive byte */
    $ t' Z1 y: _* U7 G9 o3 c0 p% C$ j
  494.         CE_High();                                /* disable device */, D" K: V  ?3 B/ u+ X
  495.         return byte;
      {- n6 r# n. ], w% @* @6 }
  496. }
    + G- o4 ~% A- S4 [7 J6 ?- Q; W
  497. 8 T: t, o/ U7 V2 S3 ?& L, g/ D
  498. /************************************************************************/& H* k8 p) W5 M9 X
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    3 J- p4 t. s- E
  500. /*                                                                                                                                                */- H: y. ?/ A( m7 @
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    , {- t) M5 u5 y; ^
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            *// m" {$ M7 |, _. E2 T/ K! i; D
  503. /* Please see the product datasheet for details.                                                  */& Q( B% m! `5 i2 W
  504. /*                                                                                                                                                */1 G0 N5 M6 A3 f% R8 _; `3 j3 ?
  505. /* Input:                                                                                                                                */# j& k# K! k! h" `& @; l. c' S# S6 ?
  506. /*                None                                                                                                                        */
    / A, Q& X5 L/ `9 v  d
  507. /*                                                                                                                                                */
    $ t" x' h( W0 Y3 l" ?9 Q- _
  508. /* Returns:                                                                                                                                */$ y" L8 {6 x; N) D6 Q7 z, }2 y
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    , [- E; M& H+ {. ?& I5 F
  510. /*                 and Device ID (8Eh)                                                                                        */
    3 e% |& q8 c( M$ {
  511. /*                                                                                                                                                */
    0 V! V) C- q$ S, K2 @
  512. /************************************************************************/" x3 ~7 ~  w. j* j$ V+ ~5 G
  513. unsigned long Jedec_ID_Read()
    " Y6 b3 b6 q) A1 D. x' P
  514. {
    0 F0 d: S4 V: g; s# l
  515.         unsigned long temp;! c# M0 Y4 y3 o3 I' G8 a, S) _( X- k3 s% V
  516.        
    & D# x* M% |5 H" f# ?! D
  517.         temp = 0;; n7 ]4 D. `, m# i: c2 m/ K% H

  518. ! A9 u9 B4 n: M
  519.         CE_Low();                                        /* enable device */8 A8 Y! `5 q# P% H6 _
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */- m: O* f  ]9 d7 s# {
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    # V( ]  G2 X4 U2 ?/ N
  522.         temp = (temp | Get_Byte()) << 8;       
    ) u/ L- l( W0 g& |% c0 [0 ]. P) I
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    + ?( P5 ^# u4 M5 y7 a( l2 U! Z
  524.         CE_High();                                                        /* disable device */) t- K- E( u& x9 B5 T4 V/ Y5 p

  525. 8 J* l( T- t% x1 f+ o
  526.         return temp;& [9 o! n# ^; t  h% Q! g
  527. }
    7 m& r# N% v$ {2 k, |+ d

  528. ' p  ?# O# n% [5 X+ W3 c' @
  529. /************************************************************************/4 X0 M* `; K$ l$ a$ t. n6 [8 N
  530. /* PROCEDURE:        Read                                                                                                        */
    ! _% S& k9 v4 `3 a' c, D, o
  531. /*                                                                                                                                                */               
    # D5 b' |3 c$ b& t" Q5 C
  532. /* This procedure reads one address of the device.  It will return the         */' q5 v: J  `* p! F( T' l
  533. /* byte read in variable byte.                                                                                        */4 O1 p, f5 e3 [* f
  534. /*                                                                                                                                                */
    2 q* @/ t  e+ _0 q2 u$ e
  535. /*                                                                                                                                                */
    - t$ W+ U' M2 o1 ]" P1 z$ n) l
  536. /*                                                                                                                                                */
    % G% }0 ~3 ~0 |5 _+ V* ?. w& Y
  537. /* Input:                                                                                                                                */
    3 Y5 n, h4 l7 {7 d3 J' g
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    + ?+ c7 p; W; r& H( C: ~2 l
  539. /*                                                                                                                                      */
    . A, T9 ]* k5 y
  540. /*                                                                                                                                                */2 Z6 f3 w* s  ?( I
  541. /* Returns:                                                                                                                                */' {* L0 x  X$ A& U# E8 h5 k& }
  542. /*                byte                                                                                                                        */
    6 |1 W6 X' ^7 V0 P# H7 ^! A! T
  543. /*                                                                                                                                                */' D# \; `! i9 I
  544. /************************************************************************/
    " @( ~7 N1 ~1 W2 M8 N% U: Y
  545. unsigned char Read(unsigned long Dst) 4 c; E- e) v2 G' }8 g$ o
  546. {8 i' C/ ]& J7 e/ q5 R" W
  547.         unsigned char byte = 0;        : l9 x: h( h+ X- o6 z; p" m
  548. + Y$ f' m" l  v6 y* ~2 [6 q" J' t$ q' t
  549.         CE_Low();                                /* enable device */- J0 u' h2 |" i1 R: }0 |. p5 {7 Q
  550.         Send_Byte(0x03);                 /* read command */
    ; E- b5 {* O( s+ }0 E
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    5 f' h& A( d2 U: a8 s0 C. }
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));7 ~. |( W3 V# }/ q( N/ t! Z2 W9 \
  553.         Send_Byte(Dst & 0xFF);& ~3 ]7 v* P  H& p6 N0 p
  554.         byte = Get_Byte();
    % W# q' U; v" {: K& ?( T* s2 u
  555.         CE_High();                                /* disable device */
    & w0 }( |/ s2 h/ a: P
  556.         return byte;                        /* return one byte read */
    ) P  {# g$ Z9 T# q# X+ \
  557. }  {5 }  }# X# _* W' v! D* J& r4 t" ~
  558. + A. E) U' z. x- f$ F8 T4 g
  559. /************************************************************************/
    $ e( }- L! I+ [$ C- j
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    1 e5 [' G( P' Y) U8 X4 H3 _# V6 t' m
  561. /*                                                                                                                                                */                * Z# o" S/ G& B! w
  562. /* This procedure reads multiple addresses of the device and stores                */2 O8 S8 F! v) n# J8 g
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    ) \: m( X+ G4 `& A
  564. /*                                                                                                                                                */
    ! H/ r3 E- S0 T/ y  S! {
  565. /* Input:                                                                                                                                */
    ' d" |8 w, n" d" j- Q( L! H
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    # B6 e& j" Y; G6 {+ A3 b1 I
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        *// i* |3 f6 h. ?2 o
  568. /*                                                                                                                                                */
    0 S6 u. j" c/ v
  569. /* Returns:                                                                                                                                */
    . e" c& h) V$ j- i7 H6 k
  570. /*                Nothing                                                                                                                        */5 A  m' v- X; j% O, {) h0 L' i
  571. /*                                                                                                                                                */
    5 u5 {6 Y/ H4 l: K# u
  572. /************************************************************************/
    ( l# E- e5 ]5 t: P5 Y
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)) Q$ Q5 e" q: Z
  574. {" c8 p* [! B" l7 O
  575.         unsigned long i = 0;
    ' B7 y4 Q% D- `4 Q7 K
  576.         CE_Low();                                        /* enable device */
    ) o4 z- }2 v3 a7 X# {( V9 y
  577.         Send_Byte(0x03);                         /* read command *// z5 W2 l1 s% b* ^. t. t
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    8 F+ n0 f+ J% v9 D- s
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));; U. z& T6 q# \2 k; ~9 V6 {3 N0 D
  580.         Send_Byte(Dst & 0xFF);( f2 Y# b. z- F% m, y& w  {7 w
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */3 w3 B* J. P: g  q
  582.         {. A- G5 k% e7 ?0 C9 l0 A/ R3 Z
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH *// `+ S, ?+ U6 Y8 c' |9 d8 I" k* e8 P& A; y
  584.         }4 @0 a. y) f0 I% k) h( G
  585.         CE_High();                                        /* disable device */
    ( Z( ]* u" x" ?% [0 _
  586. & `+ e( }* d. g; d1 h  r
  587. }
    ! `7 m7 s" r% h
  588. 2 F4 }- x! s5 G1 i  p' W  G. v
  589. /************************************************************************/
    " j# j! T: u* H+ u/ S, @* ?& k
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    7 y& a' @: o+ U  M% d2 W
  591. /*                                                                                                                                                */               
    ; H/ I' L8 g4 }. j
  592. /* This procedure reads one address of the device.  It will return the         */
    , M6 b$ |1 F0 d* W7 r; M9 O4 G- [* V7 `9 V
  593. /* byte read in variable byte.                                                                                        */4 S- F# g" |& K
  594. /*                                                                                                                                                */; k+ y9 S, z: ~. `% y( b7 ~: a
  595. /*                                                                                                                                                */
    , g) W7 P  @. C3 p% i! z+ q* t# K! ^& ?
  596. /*                                                                                                                                                */# V! k; M7 ^! T  u" {' V
  597. /* Input:                                                                                                                                */9 ]2 W/ o5 q# j
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */5 a$ d4 o4 I' J. Y4 j8 c" c& s
  599. /*                                                                                                                                      */
    9 ^' h3 y& E- a$ Q/ E
  600. /*                                                                                                                                                */
    $ v; P9 v5 Z6 j7 C+ A* ]( \8 P2 d
  601. /* Returns:                                                                                                                                */
    ) x  ^( f4 r; h/ _. k
  602. /*                byte                                                                                                                        */
    , r) Q5 _6 a( t! l3 f
  603. /*                                                                                                                                                */7 d. A, ^- y( o0 V8 A
  604. /************************************************************************/5 H9 A7 e" X1 a- t1 g& ~
  605. unsigned char HighSpeed_Read(unsigned long Dst) # }/ P; r" L8 t  F1 f* w/ T
  606. {5 s! C$ T( v# N+ G1 M% q
  607.         unsigned char byte = 0;        5 e5 A. E) V/ Z* y

  608. 4 N- s' k% B2 K/ z( ]' O2 l
  609.         CE_Low();                                /* enable device */
    ( b! j+ D% b) @/ ?
  610.         Send_Byte(0x0B);                 /* read command */
    - a6 F/ a- b' ~6 d6 J1 _
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */" Z  M0 m4 C# R  ^  y; u# K) u' s
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));4 V) f4 I8 |% y1 j) \1 t: ?! k
  613.         Send_Byte(Dst & 0xFF);
    3 S0 \" Q: W% |( O9 j# f
  614.         Send_Byte(0xFF);                /*dummy byte*/3 w1 [! q' a/ ]: G- x# z
  615.         byte = Get_Byte();9 Y3 E6 k: J/ u9 s  j5 |
  616.         CE_High();                                /* disable device */
    # U$ W4 R$ o8 r2 u9 \* Q5 A
  617.         return byte;                        /* return one byte read */- a5 U: j. X- `/ L8 {0 f
  618. }) r; s) d* u0 `/ X

  619. $ W' y6 N7 }5 ^: f2 d1 E; ?
  620. /************************************************************************/
    9 l$ C  d( E* X- A2 L) b5 Q% @
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    : }) ^6 }) ?2 }* M9 n6 a) u8 R: M
  622. /*                                                                                                                                                */                ( p) x+ n, I2 {' B5 C& {- Q8 H( l0 }
  623. /* This procedure reads multiple addresses of the device and stores                */
    - O1 X  L* ?0 \( x
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/; A$ k8 }$ q0 z/ p
  625. /*                                                                                                                                                */
    5 T' n6 }7 w, c+ S. H2 G) V  l
  626. /* Input:                                                                                                                                */8 b: R# V3 S& `$ M+ @5 O
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */1 o  e6 e: ~5 D4 R
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    9 s1 @) {' w/ O5 V
  629. /*                                                                                                                                                */1 |- _5 Q/ C0 \- ?- G
  630. /* Returns:                                                                                                                                */# K$ }) [" l, ?. O: Q% [
  631. /*                Nothing                                                                                                                        */
    8 v! N# t5 B5 |
  632. /*                                                                                                                                                *// c3 b! S4 ^5 E
  633. /************************************************************************/0 b8 X$ C" t- I* e/ r9 U  M* z
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)/ I5 e: v- K; d5 D8 Y
  635. {
      V% @( {0 ]+ h5 v. r6 S+ S
  636.         unsigned long i = 0;7 R* @0 g1 r# M+ q
  637.         CE_Low();                                        /* enable device */
    , M) F  l# i" e7 v0 @8 [/ }. K
  638.         Send_Byte(0x0B);                         /* read command */' z1 N" L% `+ B* _0 U
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
      L" \$ U% K; \: k
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ) @; J* T' G' r1 d' E( ]
  641.         Send_Byte(Dst & 0xFF);! f/ o  X' R1 Y- R) {  l( {3 W$ o
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    : D. K8 \4 `& ^
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached *// i. w& p# b+ B/ v
  644.         {
    7 m4 l! p! U4 V) @/ B
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    $ b9 A/ i* F$ m5 n
  646.         }
    2 g! y/ a8 g4 y! b3 \: y
  647.         CE_High();                                /* disable device */- X& i  ^  G1 m5 b7 t
  648. }
    ' i4 u6 o# ^8 Y' U0 X. S: ~
  649.   p* L0 _9 ^8 D' i  `8 E
  650. /************************************************************************/6 C" ]& g1 n( l5 a& I: o) j
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    , }/ W, `6 C( ?  W% f" i% ?# }
  652. /*                                                                                                                                                */  f7 E6 U* _4 H) Z
  653. /* This procedure programs one address of the device.                                        */7 J+ X# x) [, F8 \( _8 A
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    7 ^+ N0 \1 i/ d$ R# I& F! w
  655. /* block protected.                                                                                                                */
    - G; ?2 q8 y8 U4 f
  656. /*                                                                                                                                                */& N3 \/ N" f' L- w
  657. /*                                                                                                                                                */* L5 H* v1 D, a0 k: c  @8 r& K
  658. /*                                                                                                                                                */
    5 A8 A4 x4 |5 c
  659. /* Input:                                                                                                                                */
    : |6 q/ `( s9 x" \0 P5 {* D
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & s/ q; a# A* J5 Y
  661. /*                byte:                byte to be programmed                                                                */
      q: b  y7 ]6 x& l" |6 _0 V( b
  662. /*                                                                                                                                      */
    " l8 i# `; {0 J# V
  663. /*                                                                                                                                                */1 |9 D, W# V) b3 Y1 q
  664. /* Returns:                                                                                                                                */
    * J% X4 d3 w7 M$ p6 l
  665. /*                Nothing                                                                                                                        */" M$ y& L6 E8 S" z- @. v
  666. /*                                                                                                                                                */
    $ z2 V9 H: ?7 O7 X2 G
  667. /************************************************************************/6 e& B: E8 Y; I/ ?
  668. void Byte_Program(unsigned long Dst, unsigned char byte), H- [6 ?5 I7 \' q
  669. {
    + \* M3 `* i! W$ K$ k# ^% g7 Z
  670.         CE_Low();                                        /* enable device */
    " Z) M; C9 G# z
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    4 X+ e, Z- [' y2 P) u& E( y9 E; p
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */( L; y( P) ~# O& z& `
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));- P* k1 Z; r" V: t$ |
  674.         Send_Byte(Dst & 0xFF);
    ; k3 T* Q; v/ Q3 o; S  F/ n
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    & l4 V4 l+ O+ s/ A: i# K
  676.         CE_High();                                        /* disable device */: F1 h) o' u5 \0 p  J4 Q/ `( C
  677. }: c2 l2 y: o" c

  678. : n( f8 q( y& O% r2 Y: V
  679. /************************************************************************/. N2 o# v: M+ l) b. k7 H! `, K$ J
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */+ G( L0 K5 J) c& S5 X" V+ V
  681. /*                                                                                                                                                */
    2 E# ?4 [, I. g, E
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    ( N& D* W% x0 f" B) p: R  d& J
  683. /* the device:  1st data byte will be programmed into the initial                 */  X5 P5 \! W* k$ u
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    7 W6 x# V  z6 ?( B* D: f
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
      H- h8 `5 j* M5 t  j; Z
  686. /* is used to to start the AAI process.  It should be followed by                 */* Z. O: b+ O- }! P
  687. /* Auto_Add_IncB.                                                                                                                */
    " [6 l( e* V8 @
  688. /* Assumption:  Address being programmed is already erased and is NOT        */8 U  J! l1 m' Y' S  h/ Z2 s
  689. /*                                block protected.                                                                                */1 ?! S8 Y* R0 i7 e( D) k  p" D$ T5 t
  690. /*                                                                                                                                                */
    2 x5 `9 E0 p5 `7 z% R9 g
  691. /*                                                                                                                                                */3 V4 H+ w& W, F/ s: i
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */% x7 g- e; {, N' X; O& t, o5 w8 V
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    $ V! Y/ K; F2 m# w/ _
  694. /*         unless AAI is programming the last address or last address of                */5 Q, y6 S0 h0 K  ^/ F+ a+ h
  695. /*          unprotected block, which automatically exits AAI mode.                                */$ }+ j  m6 ?0 x1 l1 {4 w
  696. /*                                                                                                                                                */
    & A3 b) d6 N, K. f
  697. /* Input:                                                                                                                                */
    ( _+ u( B$ A! n# W( m
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */% `+ k" J+ I6 h4 W
  699. /*                byte1:                1st byte to be programmed                                                        */9 W7 @8 V- m  s* x( ^
  700. /*      byte1:                2nd byte to be programmed                                                        */2 j$ ~6 r2 w1 M! T- P
  701. /*                                                                                                                                                */  E9 R5 r2 O: t' X& ]" L) W
  702. /* Returns:                                                                                                                                */
    7 `0 U/ R; b; X6 x, m7 D: V
  703. /*                Nothing                                                                                                                        */
    7 q1 R; v' ~$ e) K* A
  704. /*                                                                                                                                                */
    ) X; L4 N/ ~% h! g, F$ d) l3 _: ?
  705. /************************************************************************/
    7 V4 H# J( s' z! U1 _
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    . d" g1 Z% [0 V2 n, v
  707. {. Z; `) ?7 Q# R, g& |
  708.         CE_Low();                                        /* enable device */
    2 |8 i. X9 T3 W5 t; L4 }
  709.         Send_Byte(0xAD);                        /* send AAI command */  m( S# q% z) ]9 K- q1 _0 [( n7 `/ L4 u7 f
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */1 Y9 ^, o/ B# r- f) N: M
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));& p! S" P: Z% a1 [" Q
  712.         Send_Byte(Dst & 0xFF);
    , z9 y8 G% g: s+ ?" W1 Y# D" N5 Q
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    0 [* v  Q  \$ z9 D# k( z
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */9 H' I) [. e% Y6 D3 O8 y: h
  715.         CE_High();                                        /* disable device */
    ! r. U- q4 |* g* a, O1 M4 y4 L
  716. }
    ) M8 i' ]3 m, ]; r+ o# F. s' Q( @
  717. 6 l; k0 j3 V1 I( Z! H8 K7 Y$ E
  718. /************************************************************************// a- L* z& i1 }) c. J+ L8 |
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */2 ]% |  `" n1 J1 l
  720. /*                                                                                                                                                */
    7 D) _% ^' v0 J0 w' d$ s
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    0 a0 M. z8 A: N/ p! ~: \4 C
  722. /* the device:  1st data byte will be programmed into the initial                 */
    8 q( C3 }2 T# x6 }6 W; A3 r
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */& N0 Y* G2 M- h# \
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */. K0 i; J* X$ b+ i& a% `# T- g
  725. /* is used after Auto_Address_IncA.                                                                                */
    7 p# r  i, t7 _+ y  R8 C+ l# [
  726. /* Assumption:  Address being programmed is already erased and is NOT        */- d& D/ T0 B3 p
  727. /*                                block protected.                                                                                */
    4 K5 |. g5 E- E  n; E- u
  728. /*                                                                                                                                                */3 ~% \$ C: b$ A2 o( q
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */+ u4 h! A3 a* y/ Y* q7 \' b$ H/ z
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */" `4 h6 {) q6 A9 {& {
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    - W6 \5 R" c6 J; L
  732. /*          to exit AAI mode unless AAI is programming the last address or                */& U  }) ?" S% j1 R. h
  733. /*         last address of unprotected block, which automatically exits                 */" c4 ]1 t5 ?2 I8 a, H5 l! R
  734. /*         AAI mode.                                                                                                                        */
    ) b5 ?5 W5 e+ J  d: Z, x
  735. /*                                                                                                                                                */2 t" a+ [, }' v0 s* b
  736. /* Input:                                                                                                                                */7 e0 G; M+ W1 C3 B
  737. /*                                                                                                                                                */" w9 \2 p/ p' K+ J5 K+ y) F+ f
  738. /*                byte1:                1st byte to be programmed                                                        */9 U2 ?& L6 G: w; D5 `- x
  739. /*                byte2:                2nd byte to be programmed                                                        */3 y$ i* Y8 n* |9 C1 b3 |& B  L
  740. /*                                                                                                                                      */
    , [8 l. G1 B! y% I/ }6 T+ Z
  741. /*                                                                                                                                                */2 h/ K6 Q7 G( G& ]% X0 y
  742. /* Returns:                                                                                                                                */
    # m' l) `( `' L' Y0 @# R
  743. /*                Nothing                                                                                                                        */
    % q+ T5 b$ Y& F" z9 I1 _9 T% A; e
  744. /*                                                                                                                                                */8 ?7 Y* q1 F8 X* G
  745. /************************************************************************/0 D  S) c% U  K; g* Q) O
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    , H  K- q/ l% k8 X$ L
  747. {1 O8 f2 A, b6 [5 P) V6 I6 K
  748.         CE_Low();                                        /* enable device */' T; g# h" w! c7 d2 j0 N3 A
  749.         Send_Byte(0xAD);                        /* send AAI command */2 T+ F( s. U( K/ e+ B
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */8 ^$ f$ h+ @# O" ^* ~
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */3 M! Q; |6 B" g
  752.         CE_High();                                        /* disable device */) n0 ?$ F% K1 G0 L& x7 s
  753. }
    , x% c- k- h, ^8 _' s# F0 t& C

  754. # o9 ]8 g% X3 O* |* u
  755. /************************************************************************/
    ' b. f: Y) x1 H% p
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    / f/ I* W0 c( k7 g6 ~. S5 ?
  757. /*                                                                                                                                                */  U; {/ N9 i4 x1 ~' H" Z
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    / D6 D  E( u! `1 F0 D
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    3 ^' s" c* f# @7 w" n7 O
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    3 H7 z$ C5 J1 _' u
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    ; a" ^. ~* Y. C0 P7 G
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */" D' a+ H0 J% H+ Q
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    0 e  o7 Y- o2 V& l: q6 ?  o+ [2 p
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */; U+ T) m, g9 d4 K5 j
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    7 x) S/ c5 g- s
  766. /*                                block protected.                                                                                */
    ' ~5 p5 T7 n+ t  z( Z, I8 T. A
  767. /*                                                                                                                                                */: y9 J, T9 H! [8 N+ Y
  768. /*                                                                                                                                                *// W/ ]! x3 l  T
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */+ B' l. @' ]6 Y; g4 ^
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */! e7 \( }1 c5 ~  \8 h
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */# ^0 s( }' L2 r3 r" n
  772. /*          to exit AAI mode unless AAI is programming the last address or                */. t1 Y! i) v7 x4 d
  773. /*         last address of unprotected block, which automatically exits                 */  a, H+ s9 s7 y8 H! u: M  e
  774. /*         AAI mode.                                                                                                                        */2 n. B. O8 I0 v3 P
  775. /*                                                                                                                                                */
    ) l) L. b( b/ L& `$ X# k% k# p
  776. /* Input:                                                                                                                                */
    ; e1 L" `0 u* \( m9 _* x9 S
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + T' i& r0 Z: _) l4 p
  778. /*                byte1:                1st byte to be programmed                                                        */
    % |' [% |( C  X1 I
  779. /*      byte1:                2nd byte to be programmed                                                        */8 B& \  g" A) t! C/ m
  780. /*                                                                                                                                                */! S$ c" W6 s/ v2 h# v5 W. O% ~
  781. /* Returns:                                                                                                                                */
    / ~4 k5 d. w3 `
  782. /*                Nothing                                                                                                                        */
    + \& H' P* M, K, s9 l6 L- o. v7 ^
  783. /*                                                                                                                                                */9 D* f! Q: _' f% |
  784. /************************************************************************/8 F2 W) W+ b! R
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)7 q. E6 F/ x( C9 f( p
  786. {* R" k; J6 |- u/ C5 y7 V0 j( z
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    2 o, x0 x& b: w5 C% k
  788. 6 h. @0 G5 X; K0 R
  789.         CE_Low();                                        /* enable device */2 S2 J" o  @! f2 y! E
  790.         Send_Byte(0xAD);                        /* send AAI command */
      C6 Z1 u* _4 Z# k$ `
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    3 H5 |; m8 f/ z
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));( M$ v9 N. _( [8 g. N; S8 u
  793.         Send_Byte(Dst & 0xFF);
    ! Z+ w3 K* L1 l/ j' |, Y6 j
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
      U! F& ?+ @0 h; V
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ' I# a- U& R& t$ H, k  W  M
  796.         CE_High();                                        /* disable device */( W# o1 r; x2 a. B, u. }$ K  u  x% K. f
  797.        
    8 G" Z& o+ q0 B. f/ d
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    , }% W( q0 d$ y  I

  799. 3 Z1 P! u5 i5 ^: G8 D9 ]
  800. }
    2 A: D5 y4 ~7 e; U

  801. 6 E2 r6 z8 T  |
  802. /************************************************************************/' ]6 [$ G3 I  [( o
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */9 P( C# Y- ~( {- h; L* B* Y
  804. /*                                                                                                                                                */% x: ]2 L9 i& |2 X
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */7 L5 y: w0 v/ D- l) t( Y% E' X. Q
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */, M0 |. j; r$ n0 P+ H/ B
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
      M# d  b& u; j
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    0 }1 x, f7 |3 l0 R
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */& r0 g. A8 e) J: s; U/ H4 Z* |5 A3 g# G9 I
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    4 F$ ^) O& D) e9 [% q" t
  811. /* used after Auto_Address_IncA.                                                                                */+ ^' S& \+ ]* s4 r( ^6 [1 G3 U
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    9 Y% s$ C" g8 i/ J
  813. /*                                block protected.                                                                                */7 D4 O; Q0 e6 N, m! j
  814. /*                                                                                                                                                */6 c6 T( ?* l! _6 O& u
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */: U& Y( S; y& |/ u* _
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */6 {, z4 E0 W* M* y' p" |
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */8 Z- I$ M" E4 R
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    7 c. B: G- E: L! n
  819. /*         last address of unprotected block, which automatically exits                 */3 ~1 U9 s2 o; A) w4 a
  820. /*         AAI mode.                                                                                                                        */
    * J( }: w# ?4 w2 ?3 d( T3 I# F
  821. /*                                                                                                                                                */
    - t/ d3 d1 L4 B0 h, |1 z( ~
  822. /* Input:                                                                                                                                */4 _! [) m+ a% U& d
  823. /*                                                                                                                                                */
    1 v6 h2 O% W! a- D
  824. /*                byte1:                1st byte to be programmed                                                        */
    3 P1 U: Y6 w1 _% [
  825. /*                byte2:                2nd byte to be programmed                                                        */& }% n9 q6 {! L+ H6 p" h
  826. /*                                                                                                                                      */8 A& z$ r- K, i& @
  827. /*                                                                                                                                                */
    & B  }" q3 L2 e( P6 Y
  828. /* Returns:                                                                                                                                */! }) r8 e& K: T$ p; s
  829. /*                Nothing                                                                                                                        */
    2 W  E4 v) D4 ^' i1 L) Q
  830. /*                                                                                                                                                */5 `/ L, j) }2 X" X, P+ j
  831. /************************************************************************/
    & M* J6 Z7 R* M9 Q' v. b7 \
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)" _# m0 e/ I/ T" b
  833. {
    5 Y1 o4 o4 a3 t$ Q" Q6 G
  834.         CE_Low();                                /* enable device */
    & D7 d: w, j" d8 U  X+ L8 l
  835.         Send_Byte(0xAD);                /* send AAI command */) O4 C( H9 `0 Y" z# Y8 \
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */$ C4 n* T" V( W/ N0 P
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    ; z4 W3 w# ^! h' [3 |
  838.         CE_High();                                /* disable device */
    ( \4 I5 n5 u$ \7 }* i0 x& L1 |
  839. 4 i: g7 [/ z5 g& q
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
      O: A% n6 s2 j
  841. 0 m: P* B/ L+ N* L8 K. ~8 D) \' c4 Z
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    ! F1 v% x& T$ S; p/ ]7 i% C6 R
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */6 P) z8 \6 K9 j  A
  844. }
      z& G8 I8 {( n0 R3 c

  845. 0 f( l5 r( _9 w: n+ V: A6 M
  846. /************************************************************************/4 B# `1 q1 R# i
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    + J1 a( [6 w; {% W
  848. /*                                                                                                                                                */7 J. h7 q! X. S) [
  849. /* This procedure erases the entire Chip.                                                                */; @; A' \8 l$ |" }, Z8 \/ D7 N
  850. /*                                                                                                                                                */
    + G! B2 F  k  R  U% q5 W
  851. /* Input:                                                                                                                                */* Y9 l7 Q5 ]3 s1 S, y" Q
  852. /*                None                                                                                                                        */; F: Q  ]* |& h! _
  853. /*                                                                                                                                                */0 P! m. N6 I. p, y' G
  854. /* Returns:                                                                                                                                */( ^7 p6 P. z. u9 u( I
  855. /*                Nothing                                                                                                                        */
    ; {3 Q7 C% [1 I/ _& N% q
  856. /************************************************************************/: U0 Y# X  n% D7 B. h
  857. void Chip_Erase(). t5 R& x$ r& p. h
  858. {                                               
    ) n9 N' U. s  R
  859.         CE_Low();                                /* enable device */
    3 I, G  ]  [/ j/ K4 e
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    " x# ~1 R# y& s" ~
  861.         CE_High();                                /* disable device */0 c* W* M. ^5 F8 Z- x0 A
  862. }
    & g2 E1 e6 D; H- i- S  l" I0 B& h
  863. 1 x* o$ f8 X1 f* G
  864. /************************************************************************/2 Y7 b, b4 @7 c' C+ g
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    0 q) P; o* H& r) d) z+ F
  866. /*                                                                                                                                                */
    + r$ Y# z$ V- I% D
  867. /* This procedure Sector Erases the Chip.                                                                */
    8 p: T6 w2 t5 O# ]& J- U0 z
  868. /*                                                                                                                                                */  q3 k! W* _% X6 E  y3 Z! `
  869. /* Input:                                                                                                                                */# Q7 q" Y/ r& M9 t& B! b
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    , T; s% s- \, S1 x/ N* s7 O
  871. /*                                                                                                                                                */
    : Y. Y  }7 ?  g: p5 |
  872. /* Returns:                                                                                                                                */4 ~$ N7 o) Q* o/ c. s4 h9 [
  873. /*                Nothing                                                                                                                        */  N* |1 p$ r# s1 v+ V
  874. /************************************************************************/
    , g) s8 _4 m& y# T# I
  875. void Sector_Erase(unsigned long Dst)' y0 ?" u1 W0 [; S  m! r" _' E: E
  876. {
    0 Z* s- v) ^8 ^3 A' H4 A- I7 x' X

  877. 0 a" o1 I, K& D" ?

  878. / }* \/ n& s  Q& j( B7 @& N
  879.         CE_Low();                                        /* enable device */& R& C+ N( V# G8 K: w" c8 B
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    6 }2 n" |) Q: G# V* l! }
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ! q' |2 Z) W- f6 z" \
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    3 X, R# ]5 L$ i  r
  883.         Send_Byte(Dst & 0xFF);
    6 [, R& A: b) i9 {6 P
  884.         CE_High();                                        /* disable device */6 S* G+ Q* l4 E) g5 ]
  885. }       
    - C% l: ~1 h+ K( u. s* p1 ]
  886. * _" d, n. b8 X6 y4 d( B
  887. /************************************************************************/& u4 P* d& E( E! O. p  D' A
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    & w; W! C7 L8 X) V1 p
  889. /*                                                                                                                                                */
    # R7 q4 T0 T( q) A* T6 b
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    3 N, P- A5 X, r
  891. /*                                                                                                                                                */4 i( S9 i- w0 M
  892. /* Input:                                                                                                                                */
    7 B: ]  D; Z* Q2 W
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */9 L1 }0 E  j) A" ]4 B* W8 w8 q
  894. /*                                                                                                                                                */* A; e& C0 l2 z3 I0 A. `
  895. /* Returns:                                                                                                                                */* Q' P  h2 D* O! G  E" o
  896. /*                Nothing                                                                                                                        */
    + P7 o( S- g4 g8 J+ a
  897. /************************************************************************/
    3 u4 V8 w  M5 K( Y* I: }
  898. void Block_Erase_32K(unsigned long Dst)+ G' x1 }, G0 V1 g- c
  899. {+ A0 T( r6 z3 f5 ^: o+ C" j$ R$ C
  900.         CE_Low();                                        /* enable device */
    & C3 s; m5 P1 B6 v
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    0 W" y# z  |9 a" p4 k
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    " b. G" G& Q* [+ w+ @' O8 _9 r
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
      ?' `+ ~# `% {6 c' U$ S
  904.         Send_Byte(Dst & 0xFF);
    # E7 z( H- v- M1 M  \
  905.         CE_High();                                        /* disable device */
    7 u+ ^3 L4 T+ L' h7 u* G- O+ z
  906. }6 g* y7 y* p6 f. ?, F" Y
  907. ) i. V( u- j3 T5 p
  908. /************************************************************************/
    : v  ~0 u& P3 g
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */# ?8 e$ k7 \9 v: {+ B* S5 u7 V1 P
  910. /*                                                                                                                                                */  c* E9 e: M, s( f8 A$ s
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ; ?) X+ C; Y7 u2 j1 }
  912. /*                                                                                                                                                */# @; Q$ D$ r# ]& Q
  913. /* Input:                                                                                                                                */
    9 A! N5 {- t& K
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    # U, m& f. C* U9 ~
  915. /*                                                                                                                                                */
    9 b5 A( n9 D" P3 s
  916. /* Returns:                                                                                                                                */
    1 B3 j8 n4 m3 Q; H# b
  917. /*                Nothing                                                                                                                        */: K1 g$ S. |) Z. g: J
  918. /************************************************************************/
    1 K  j$ ?9 F9 g9 m; G; F- H
  919. void Block_Erase_64K(unsigned long Dst)
      y9 z) Z5 P3 ^9 E7 f- y, F% _
  920. {4 O; W) |6 r2 Q
  921.         CE_Low();                                        /* enable device */3 ]* W6 _0 O' ?1 i4 r
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */- c& I' ?) U4 j
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */+ g3 |( g' w" w; O2 R, g" f
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));- T/ G/ Z( y, _/ w. O7 z
  925.         Send_Byte(Dst & 0xFF);
    4 S% c3 H. U) E1 G) L+ D
  926.         CE_High();                                        /* disable device */) \# o( K1 @) Q) @4 d$ Y
  927. }2 [4 G. B; m: g" d: H
  928. ! S& r, c% D! M% Q- q7 o! ~
  929. /************************************************************************/$ S1 L- l! N% t2 g* G# a5 ?
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    & L5 R5 t! |5 l* a1 M6 {2 A
  931. /*                                                                                                                                                */
    9 \. |% W5 b$ s$ B7 T/ m
  932. /* This procedure waits until device is no longer busy (can be used by        */
    $ g/ T. W0 I* Y8 g0 j6 P
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */3 Y) M* `! ]8 L: }& i, m
  934. /*                                                                                                                                                */- m6 C+ h+ `' F9 X/ g* Z: K
  935. /* Input:                                                                                                                                */8 e) c% d& O$ {( s9 P. i" ?
  936. /*                None                                                                                                                        */2 l, h# P+ x: y, q
  937. /*                                                                                                                                                */6 c& S$ v# V5 P% V
  938. /* Returns:                                                                                                                                */5 t/ ^" s+ \$ k( Q+ Y
  939. /*                Nothing                                                                                                                        */
    % t* r% `+ c7 G
  940. /************************************************************************/
    / R8 V' T: d& P
  941. void Wait_Busy()
    : _0 ~; g# ~6 B% q5 ^
  942. {
    4 G" Q1 K# Z/ ~3 }5 X* a1 j6 {4 q
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    $ V( Q" B& B* l/ ]5 t# l( K
  944.                 Read_Status_Register();% [% M" B( f% {0 C/ Z3 |
  945. }" n( }6 c7 ]9 g# I* f4 b) ?; [( s

  946.   d4 s: z1 l/ ]6 N3 b& ]! G" s" H6 Y
  947. /************************************************************************/
    1 _1 |! \8 M" v* j+ k
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    - l: m* T* h$ e* A. N# E2 [
  949. /*                                                                                                                                                */
    0 ^2 Z( n1 N1 y& R
  950. /* This procedure waits until device is no longer busy for AAI mode.        */, Z' z- l3 d: S2 S* ]+ _
  951. /*                                                                                                                                                */
    . i" n1 g. j9 v! {% S( I3 m
  952. /* Input:                                                                                                                                */  Z# g" F7 `8 ]$ a$ @
  953. /*                None                                                                                                                        */, ^" f0 _1 M3 P/ ]4 U" z7 p
  954. /*                                                                                                                                                */
    : E' y% o9 v6 _, O
  955. /* Returns:                                                                                                                                */1 y4 ~8 Y+ ?7 n5 x& z$ A; N% {
  956. /*                Nothing                                                                                                                        */& a! s8 ~2 \! V7 q% s/ q3 f
  957. /************************************************************************/! f5 x) X  U  x2 B+ x. d: x
  958. void Wait_Busy_AAI()
    1 }3 Y3 s0 v- X- T; P1 f/ v
  959. {3 c& d6 ]$ I5 p
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    2 t1 q. P3 T+ _# F3 U" @
  961.                 Read_Status_Register();6 Q2 z4 s! U1 _$ |% q* w# U
  962. }
    $ o; G9 {4 D9 \) f2 Q

  963. " H' o; V% W* J, |$ k) A
  964. /************************************************************************/
    5 ~. i8 T/ h% e: S- F5 O, j# Z
  965. /* PROCEDURE: WREN_Check                                                                                                */& I/ `' d+ g( S, C" ^, X4 N
  966. /*                                                                                                                                                */
    5 t8 t5 W* _4 |& ?" r; |0 }, A1 S
  967. /* This procedure checks to see if WEL bit set before program/erase.        */7 D2 N4 G, b9 G4 Q- t
  968. /*                                                                                                                                                */1 u5 Y( q2 X1 p0 y+ ~
  969. /* Input:                                                                                                                                */+ M8 D' ]/ ^& L( X
  970. /*                None                                                                                                                        */
    5 y$ Q& `) R9 w! k( d8 y% i$ l
  971. /*                                                                                                                                                */
    1 }+ d# ?* `: G8 y3 O- Z/ d
  972. /* Returns:                                                                                                                                */
    + A8 T  z1 M( O7 W7 N0 |# Q1 ]  p
  973. /*                Nothing                                                                                                                        */
    1 k& c4 G, P3 A9 d2 l$ @- ~
  974. /************************************************************************/
    5 C* D% S' c5 n. \+ }) k
  975. void WREN_Check()* o) `$ s, i9 J8 s$ P
  976. {1 q8 G5 b$ ]( v3 M. D3 Z4 @
  977.         unsigned char byte;$ w7 a2 O" b' C- I; t( p
  978.         byte = Read_Status_Register();        /* read the status register */
    , X9 H7 `& v; \
  979.         if (byte != 0x02)                /* verify that WEL bit is set */4 _8 W4 q) `; v
  980.         {
    * ]9 V" w2 v  W- x& U6 a* }
  981.                 while(1)
    7 S+ c! o4 x; I# Q3 s
  982.                         /* add source code or statements for this file */. w: ?- y4 V- J
  983.                         /* to compile                                  */9 x  J4 c8 R: K* I9 l; }
  984.                         /* i.e. option: insert a display to view error on LED? */
    " ^0 U4 B+ K5 `. p8 |0 Y
  985.                  & Y1 W$ S. E7 W5 x; {
  986.         }# g3 @% x- R' s6 C. l* ~! g
  987. }
    - S% S  B/ {" q8 f0 A

  988. + [5 k: v" r! x! Q9 p1 u! T
  989. /************************************************************************/
    1 p3 x" z6 t" D7 o3 ^
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    ; U; ^0 Z  R  l$ w5 J8 z5 b- H
  991. /*                                                                                                                                                */# ?+ J- t* x4 f( I3 }2 H. Y- u
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    . m6 v0 d( ^) {: q# @! o4 g
  993. /*                                                                                                                                                */
    ; H4 R; S7 ~) s& X2 F1 K* T
  994. /* Input:                                                                                                                                */( f. T4 K" q0 l1 F
  995. /*                None                                                                                                                        */; u6 R) N. C% b  a& p
  996. /*                                                                                                                                                */
    - K. A9 X+ `8 h) u& H. Y0 }
  997. /* Returns:                                                                                                                                */$ r! K. s$ R# q; \$ f8 F
  998. /*                Nothing                                                                                                                        *// V7 x1 B/ C5 G) b( K; P
  999. /************************************************************************/5 O, x) }3 {3 D6 G% f
  1000. void WREN_AAI_Check(). \. J: I' J0 g: x6 \! n5 S( B
  1001. {6 q& _  @% e+ W5 f" A
  1002.         unsigned char byte;
    : w  z1 f* M. O9 g' Q
  1003.         byte = Read_Status_Register();        /* read the status register */
    " ?- ]3 U( @( l0 h
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */- l# R( L8 e: a! D
  1005.         {
    / i) t6 e3 O  j4 m* c% ]. d& E
  1006.                 while(1)               
    . ], ?7 W9 t' V% H% n* A
  1007.                         /* add source code or statements for this file */
    0 y$ I( ?/ h, }: w
  1008.                         /* to compile                                  */
    / l3 H) }+ h; O2 R& E
  1009.                         /* i.e. option: insert a display to view error on LED? */
    8 ~* m$ p  S; k$ g* F

  1010. + n/ j4 o6 n1 Y" ~0 `* A
  1011.         }
    $ W  |; }' P4 ^" h
  1012. }
    % ?+ b: f' Q3 O2 c& J8 L

  1013. : o% z+ L1 K# ~/ Y
  1014. /************************************************************************/5 p8 i- [$ v$ I5 k$ {2 e
  1015. /* PROCEDURE: Verify                                                                                                        */5 O% x: R) \! x8 j
  1016. /*                                                                                                                                                */
    3 O7 |0 }7 ^1 P6 @; N( v# z
  1017. /* This procedure checks to see if the correct byte has be read.                */% z: d; g% ]0 ^5 s% `; _  ~
  1018. /*                                                                                                                                                */
    9 N( D  G) ]. f
  1019. /* Input:                                                                                                                                */
    2 O6 C" h# u- W  M
  1020. /*                byte:                byte read                                                                                        */
    " j  Z6 ~) \1 F+ t: |; k+ a0 N; z
  1021. /*                cor_byte:        correct_byte that should be read                                        */3 J4 n) K" `  o$ a  T# f
  1022. /*                                                                                                                                                */
    * p" p1 O" b! q+ f- ^
  1023. /* Returns:                                                                                                                                */0 G/ L5 _4 ]* j1 r
  1024. /*                Nothing                                                                                                                        */
    ( D% Q1 j  G# `. ~3 ^
  1025. /************************************************************************/
    ' {7 B2 P# v4 I2 Y/ z  Q7 m0 d+ c
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    # \5 g1 b2 U4 C- q1 x  T# S
  1027. {- k8 P' z* W( y
  1028.         if (byte != cor_byte)( @& p- s1 X- M  r
  1029.         {( c# q5 R. n2 D+ U9 W
  1030.                 while(1)* r- p2 N( z! L5 @; e2 g
  1031.                         /* add source code or statement for this file */
    6 Z6 X3 |3 X' d) _& d' H/ @
  1032.                         /* to compile                                  */
    % n  Q: ~) o! P2 b0 ^$ C& d
  1033.                         /* i.e. option: insert a display to view error on LED? */. E% E- x: O* d  G7 K% B/ K; I4 h0 w
  1034.                
    & g. |+ b! x0 L4 L- U& ?
  1035.         }& R  i1 W# g, H9 a, f
  1036. }3 I8 K6 q; m+ }) N* o

  1037. / K2 H& G- G' w0 z1 C3 [

  1038. ) R5 K1 W: {1 ?% i# B% A* x
  1039. int main()5 z/ Z3 j5 H) o5 m) v. H  K
  1040. {
    : d" q* K9 t  C$ u

  1041. 2 i' b0 W+ J7 F* s- f
  1042. return 0;6 S) g3 u3 X6 l( }( s( w6 }( z
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:$ K! [& W! d0 I" X7 F, W6 Y" d& ^
   main()
% f5 M& `. U, r; o& S0 I- V0 w6 ]   里面怎么是空的呢?) d' \% M# l+ C7 o# j9 O; U! F$ S
   发一份给我吧! k' x+ ]: G( e  |4 E  z
mail:luyijun2005@hotmail.com
; _( ~0 y7 V6 q9 P/ 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才能执行。
& }) z, [& I  F4 \* o$ I
8 t; I5 U. {- |6 U7 u5 P# J! w[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。9 z* P7 f2 V3 q4 ^4 I) {- L
EC的代码在哪跑,你看DS的说明,每个EC都不同的。# m. u( f2 P  M1 U$ Q: t2 M8 c; `: m9 }
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?9 L8 j; d) s5 x8 o8 [' |
上面几个问题是你没看任何东西而白问。
: g" a' ]3 Q$ y  X* q
! {6 [' `$ ^5 q2 \' X- p8 a/ r8 o, c至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
1 r6 B, e3 V; d% J3 o( Q' O- H& R3 K( E2 q  d1 a
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
; F) h- ?: H  {$ \2 p! c: u) H, f! D. J) A
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
) e+ W0 Z7 A6 d  E2 D7 b. e
. M6 }9 i! m% x2 Q5 m4 P关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
1 C# @' p/ W+ B% S2 K# h. @: t0 ]* ^1 g8 W3 i' a1 G& A
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
8 q3 j# E9 t2 K6 U似乎要把SPI能support 到最大,这EC chip应该有好卖点' b6 ]& h# B3 K/ e0 y, R
BIOS功能要不要强大,也就决定了SPI Flach的大小
- p: L9 U3 }5 `我是这么想的~让OEM去决定要挂多大!* v, b) k- X- C( [* Z6 ^" C3 _
如果我司有BIOS工程师就好了~哈
7 m/ O5 V/ v$ z- H+ S/ R6 {WPCE775应该算很新的东西,来看它支持到多大?
; y1 S/ w+ A+ s- w# V
8 w! R9 I( {( k2 ]: Y另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte! k5 z/ o5 \# V+ g0 n: {1 t
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.3 J" R5 L1 G/ k3 Y( ?1 M
- k1 b+ O$ _4 x- ]) @) L
这份driver收下~希望以后有用到
( t2 X# [0 N( r0 C1 Z# G/ l谢谢bini大大! |+ r+ T- U! w: r9 P
5 @6 c/ \. `( @) T- n1 ]7 {% r3 z
很新很新的新手,如有错误请指正 (准备看第二家的EC SPEC)
回复

使用道具 举报

发表于 2009-7-18 15:16:34 | 显示全部楼层
我也有份汇编的DOS下的烧写代码,SST 1MB的 flash可以用。我不知道为什么AFUDOS为什么不能工作,AMI好象没有发送94 CMD下来,AFUDOS直接就说不支持。搞的下BIOS非要自己写个程序,烦的很啊。
回复

使用道具 举报

发表于 2009-8-13 10:59:30 | 显示全部楼层
前端时间小弟也在windows系统下写了一个并口到SST25VF080B的烧写程序......
回复

使用道具 举报

发表于 2009-8-17 16:47:36 | 显示全部楼层

这个函数看不懂Poll_SO()

void Poll_SO()3 Q7 ?, s( Q" v$ e, S3 c+ B# z
{
# U" u$ a9 e  K0 o& _        unsigned char temp = 0;
+ T# p+ o& Q" v* E        CE_Low();
: R; h( K; {. Q, f& G* o2 H    while (temp == 0x00)        /* waste time until not busy */* w8 ]3 c5 A: e( j( S5 l5 N
                temp = SO;
% R% S- P6 \, d& ]9 K9 {8 Z% |        CE_High();
2 ?. R3 z: G. M" E6 d4 v0 l& j}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)  k  z' I. G" b3 Y+ J. x( P
{. w& g. F" l/ O1 H9 W) F
        % y! W- ]" O/ O# ]6 z& V5 ]0 o
        unsigned char i = 0;
/ x# M4 K' i8 X5 Z1 G" y* G/ u        for (i = 0; i < 8; i++)4 s' T- a$ T2 J1 q- `
        {
' I( g" g0 p5 ~' W( V. j               
0 T/ \2 X. w1 W                if ((out & 0x80) == 0x80)        /* check if MSB is high */0 F: P' D1 M) O- O+ M4 ^2 R
                        SI = 1;  I' r  v1 w# l$ q+ l
                else0 @/ Q9 D0 T. O+ I, I5 M' l: D! n/ l
                        SI = 0;                                /* if not, set to low */
3 v5 j7 R8 L" X) u7 I 问              SCK = 1;                                /* toggle clock high */
" j+ {! B" V6 T1 h   题            out = (out << 1);                /* shift 1 place for next bit */# ^* L  B" P# Y  Z& Y
                SCK = 0;                                /* toggle clock low */
) ~& U  P& }; b, c" R3 Y6 _        }1 U- N  R+ {0 \, F
}
4 a' m9 u. {% z3 H5 x& w 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-2 10:49 , Processed in 0.047997 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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