找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 52451|回复: 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 Driver0 p5 {9 O/ o; s3 n- \8 _4 I
  2. 3 z% k0 J: |7 q5 ^
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory; ?$ z1 A! m  m, z- M

  4. / Q: G4 @, N, t
  5. November 4th, 2005, Rev. 1.0
    % \1 ^/ r$ `- }3 [/ @

  6. 1 P3 a, ]+ e9 M8 m0 ^. A
  7. ABOUT THE SOFTWARE
    # B+ ^6 h5 `) r
  8. This application note provides software driver examples for SST25VF080B,
    0 b% V/ B! I, w# E
  9. Serial Flash. Extensive comments are included in each routine to describe
    ' ~% A( p! Z+ H* _& Z
  10. the function of each routine.  The interface coding uses polling method 2 V" ~6 Y- A! ^# \/ m
  11. rather than the SPI protocol to interface with these serial devices.  The+ e) S2 N2 Z4 B9 c" x% w' [
  12. functions are differentiated below in terms of the communication protocols
    4 T2 m2 `0 r% _4 D
  13. (uses Mode 0) and specific device operation instructions. This code has been
    . u+ h2 s# i( z% R
  14. designed to compile using the Keil compiler.0 s0 |' D) Q; \& n; ^

  15. * B3 p# U$ ~/ t

  16. * n9 G1 X3 I$ |2 ~
  17. ABOUT THE SST25VF080B0 H- ~# C3 p/ ~
  18.   l/ |1 {1 T* w$ E  D
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    2 j- ]' R/ x9 E5 Q' W7 E
  20. conjunction with this application note for a complete understanding
    8 `. b* v3 R# u9 q' O7 C- S7 u' M
  21. of the device.. D! I, k% f  L- t2 J8 V

  22. 5 o5 q% A; X; K, }  E8 [* B
  23. 2 F+ a* \9 G) k0 O2 v' y
  24. Device Communication Protocol(pinout related) functions:
    8 _. r6 u. X5 p
  25. ( I$ W1 J$ C9 c. Y4 F
  26. Functions                                    Function$ v0 H) y8 j6 I. M
  27. ------------------------------------------------------------------6 k1 w0 ~% p$ l" X
  28. init                                        Initializes clock to set up mode 0.2 ^& }  I; r+ l( ~! C) Y2 `
  29. Send_Byte                                Sends one byte using SI pin to send and
    $ Z) c+ Y1 T5 R
  30.                                                 shift out 1-bit per clock rising edge2 `8 T, s. c- L0 n: ]1 |. f6 ]" O
  31. Get_Byte                                Receives one byte using SO pin to receive and shift   p! b& ]4 S- P5 x2 t
  32.                                                 in 1-bit per clock falling edge
    / S% V9 _. v# G; _$ ~; Z, p9 @
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    - l" N+ g: u9 D7 N* _5 @4 E* @/ q
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high9 e8 l- ^& j5 u- L6 s2 U8 n
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    2 R* ~9 q& M: }
  36. Hold_Low                                Clears Hold pin to make serial flash hold" y* B/ o$ L: C1 k& W6 w9 c2 J& Y$ |
  37. Unhold                                        Unholds the serial flash
    3 w; {! d2 v) y
  38. WP_Low                                        Clears WP pin to make serial flash write protected* q5 L2 r. q# t4 O. e( W7 Q8 D
  39. UnWP                                        Disables write protection pin
    / a* B+ h4 R/ j7 T' G- i" o6 i
  40. - N0 t  c# o% |0 L& n
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code- F1 Z6 y: `: {6 Q( E: l; Q2 a% C
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your8 F3 Z" k0 t+ K+ @$ T! E
  43. software which should reflect your hardware interfaced.            `7 Q% g) Y7 w8 E- ^, q2 W# g+ R

  44.   N% d. v, P+ @
  45. * x$ b4 a8 f. r' y8 K2 W
  46. Device Operation Instruction functions:. D5 ^8 C- K3 K! s, m3 r3 w: i" R

  47. 4 Y. l& M2 r$ k+ j5 T
  48. Functions                                    Function4 x! W4 }! f) A7 j' q9 j" U
  49. ------------------------------------------------------------------
    6 k. O8 j3 }% j6 r
  50. Read_Status_Register        Reads the status register of the serial flash
    - _% n# T- Y( w0 s8 Y5 W. f
  51. EWSR                                        Enables the Write Status Register
    3 e" c" D4 x: A* @
  52. WRSR                                        Performs a write to the status register
    6 y7 B# Q* [% x7 }% h! Y
  53. WREN                                        Write enables the serial flash
    $ C9 p" {' x: B2 S1 H2 L& f) Z
  54. WRDI                                        Write disables the serial flash
    - [* q" J3 C2 N  L) i
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    $ l" o7 ]+ i4 V: s# }6 O/ N6 S
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming3 z1 }# U' Y# `( m: Y  f' w
  57. Read_ID                                        Reads the manufacturer ID and device ID* P* s8 ?2 I& `" w7 _; |
  58. Jedec_ID_Read                        Reads the Jedec ID( _  R5 }+ @! M
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)+ g% W0 d1 U& A
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)% f4 q% ~: ^6 g$ J% w. Q$ _
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    # w& s9 B7 E" z* i/ X
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency): {( K! g* O1 N  z3 ~  e
  63. Byte_Program                        Program one byte to the serial flash
    8 C9 |9 Z& P( n; ^1 S
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    ! b, B! B5 P. ^9 [1 W) p
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation, T# z& v$ ~- r6 V' k) y
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY# R3 M6 X" t) Q, r, q
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY9 y6 S* L- O9 o4 W0 }/ z
  68. Chip_Erase                                Erases entire serial flash; l$ e7 u; G5 P4 t0 ^+ I/ w* y
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    0 ]& f1 [. v! q: [
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash( {, J" E* u2 }. J& e6 X
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash* w! O/ V4 D: ]$ p6 X, y
  72. Wait_Busy                                Polls status register until busy bit is low' S/ r( c3 p7 Y; f. _: P! |' r+ P# j
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    / `! l: Z' c  x/ P$ @' e- c& c5 r
  74. WREN_Check                                Checks to see if WEL is set/ S1 T- T# }" M* w
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set! M2 G; w1 e, Z; ?

  76. , a4 i& N. G( J0 T  O4 |* [% _

  77. * J8 e0 v; B# [# r! H
  78. & s8 [; V) Z, s6 N
  79.                                                                      4 |6 y# _- j7 n% _. p  k; X1 I7 \. {) ~
  80. "C" LANGUAGE DRIVERS + i9 X5 Y" P. K. G- c

  81. / h8 `, F6 e' a7 Q
  82. /********************************************************************/. Q# |/ A* C3 x% }
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    : \, b. ~+ v. i( {
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
      ~0 _+ R& T$ n( r# v8 r3 B( L. p* q
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */9 G0 J/ D8 L8 h7 ?1 B3 k! ^; Z1 E
  86. /*                                                                  */$ ?5 z: L! |2 \8 h, `2 G
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    5 _8 ?5 n* R8 }& a! ~7 e% p4 [% i
  88. /*                                                                  */! A- j* n% F5 u6 Z" `
  89. /*                                                                                                                                        */2 a% I6 \. m) p" \! z/ U
  90. /********************************************************************/9 C$ M- @' y6 v& T/ a' O/ K4 T+ e, H

  91.   p# a( V( _, b5 |  S
  92. #include <stdio.h>3 i' _1 N6 K! n6 j
  93. #include <stdlib.h>2 P$ B/ d% X) ^! X2 m* l

  94. ) k5 `+ [8 E$ g# p" i7 A
  95. /* Function Prototypes */
    5 g% g" m5 A9 x8 @4 v) M7 d8 @

  96. 4 \* Q. v* r4 `6 N# |  q' n$ K
  97. void init();
    " W5 }# Z$ N" J6 F8 x. L( N5 k
  98. void Send_Byte(unsigned char out);# y& [) C2 L1 K7 V2 r" u' d" z
  99. unsigned char Get_Byte();
    9 p6 x+ W" x; o) f3 U( }- M, P" g
  100. void Poll_SO();
    3 d+ [3 i/ G4 b/ ^
  101. void CE_High();6 U5 A) G) c6 N
  102. void CE_Low();$ d# o2 J0 t' @5 K- L
  103. void Hold_Low();; W9 b' r8 g' ^
  104. void Unhold();& V& m- ~  q1 o- i- N; ^" ?8 w
  105. void WP_Low();
    - D  V% T1 l" T% A6 }: @5 u( Y
  106. void UnWP();4 m% a8 s: h" n- o4 _/ }0 C
  107. unsigned char Read_Status_Register();! P- c% t# T( Q: P2 l  R" }. H! I0 F
  108. void EWSR();4 @, U# R/ r! [0 ^1 y
  109. void WRSR(byte);3 f- u" U- B. r. x, D; i; S: c
  110. void WREN();
    - c3 r3 Z- X, {' H7 m% c1 x: a
  111. void WRDI();
    2 U+ [% ?; ?. \# }
  112. void EBSY();" B; X2 G) q) G, {3 F
  113. void DBSY();
    - E) P7 k: X+ e& V+ J) ^
  114. unsigned char Read_ID(ID_addr);
    & S( S- @9 o$ ^6 I2 o4 O
  115. unsigned long Jedec_ID_Read(); 6 E  b2 m" X  b( m( c2 F
  116. unsigned char Read(unsigned long Dst);+ R3 N6 z# d/ p& Q+ {  \7 i
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    $ {4 s7 t$ Q4 }: j* E, U+ x
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    # N; O2 r2 F0 H
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);9 ^2 W0 V) f  x& Y% _
  120. void Byte_Program(unsigned long Dst, unsigned char byte);/ p! m) F5 P; c0 G( o1 |* j
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);. L5 E3 G! D8 l" N( b! I
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    7 d7 y0 @  b2 u% A+ g" X
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    3 f' Z' A: R- W  s1 w. g) e) V
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    . _; N2 I0 I( o5 x% q+ p7 c9 c
  125. void Chip_Erase();
    1 d  ~3 l- c9 o8 Y% Z$ E
  126. void Sector_Erase(unsigned long Dst);  f; |8 M# |8 i
  127. void Block_Erase_32K(unsigned long Dst);
    1 C" H4 {5 R+ X
  128. void Block_Erase_64K(unsigned long Dst);: F1 u% V- G) Q/ g. T- Q
  129. void Wait_Busy();! V3 W: @: O0 e- m5 ^/ K! r
  130. void Wait_Busy_AAI();2 g1 V9 b4 r' l' I
  131. void WREN_Check();
    & F0 T/ m6 d) E+ c4 N  q
  132. void WREN_AAI_Check();
    * m$ z/ ?# c/ _9 f/ O
  133.   p* @1 Q& z/ J7 k$ ]- t
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    ( n0 L7 ?' o4 ?0 F( Y
  135. + f; P) ^  Y- o) ]0 J2 k
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    4 f- Z& A- A! D5 \0 I
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    % }  o7 H7 u9 Z1 G0 j
  138.   P4 E& L$ d. v- G, Z
  139. /************************************************************************/
    ) D' A. u: {1 z* X
  140. /* PROCEDURE: init                                                                                                                */
    0 z# m2 o/ g; [  U4 _$ v3 ]; K1 w
  141. /*                                                                                                                                                */  K& G! N' A0 ~) j+ a: |
  142. /* This procedure initializes the SCK to low. Must be called prior to         */9 z3 I# M+ _  x5 f  P+ k/ v; x
  143. /* setting up mode 0.                                                                                                        */9 O# ~" {2 |) \. L9 A; z1 [
  144. /*                                                                                                                                                */
    3 M- T( D* i( s0 y2 q/ g  K* e
  145. /* Input:                                                                                                                                */0 N8 |9 `4 w2 a; ]
  146. /*                None                                                                                                                        */
    6 ?$ ?% K3 l! R2 A
  147. /*                                                                                                                                                */8 m: v: M4 @) t4 @8 G. W
  148. /* Output:                                                                                                                                */
    - C: O" _( k5 y1 x; ~
  149. /*                SCK                                                                                                                                */. A; z" c1 r; N9 _8 d
  150. /************************************************************************/) D% e, e7 i$ A" I% }
  151. void init()* W# y( i4 g& v/ |4 }
  152. {, h9 E! }" j* z3 k
  153.         SCK = 0;        /* set clock to low initial state */* \. z* \' y7 F: \* c5 e
  154. }
      G2 d: R5 N. x

  155. 1 [6 s. U4 X0 g* W4 Z1 N  G. {
  156. /************************************************************************/9 D& }1 _/ F+ v" t' P
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    * D" \5 N9 K% _, I* \
  158. /*                                                                                                                                                */
    " q# H: Q" S2 Q7 j0 b, `$ f/ J
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    ' J- X9 d5 V8 K% N- K; p$ l0 x6 ^4 |5 V
  160. /* edge on the the SI pin(LSB 1st).                                                                                */' @; y  j; z  q; |! C( _3 b. G
  161. /*                                                                                                                                                */2 b5 m& [, I% D# O% E
  162. /* Input:                                                                                                                                */
    1 y2 A. ?! N7 S% D
  163. /*                out                                                                                                                                */3 ^6 R4 R9 C- E9 b
  164. /*                                                                                                                                                */
    / l! W, O5 ^. W8 Z
  165. /* Output:                                                                                                                                */
    3 J5 n/ z4 Q1 C
  166. /*                SI                                                                                                                                */
    * N: M5 y. ~& s" t: w1 a
  167. /************************************************************************/: G# }8 A4 P& z4 D0 p# T, H8 X/ A! K/ o- F
  168. void Send_Byte(unsigned char out)
    0 A, H/ R& e  F* k5 ~- E- Y
  169. {& J) _2 u' M8 H
  170.         ) M) @4 e2 i9 \7 r4 _, [. W0 y  D
  171.         unsigned char i = 0;) Q8 H$ X5 q9 U4 d
  172.         for (i = 0; i < 8; i++)
    5 H* D3 z$ L3 W0 Y9 {
  173.         {; p/ U7 ~; G% }- ]" o
  174.                 % q1 t+ a9 s4 r
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */: _8 `9 b% g7 b
  176.                         SI = 1;
    # R8 M; e6 s6 j/ B4 G. E# q
  177.                 else
    6 ]0 y1 p5 F5 t
  178.                         SI = 0;                                /* if not, set to low */: D5 L! h- Q, U/ ?/ F& i0 M" @
  179.                 SCK = 1;                                /* toggle clock high */
    . j# ^, d2 Q" q$ T- S. |0 u
  180.                 out = (out << 1);                /* shift 1 place for next bit */$ k& t# k3 F9 E0 V- h: M$ w" D
  181.                 SCK = 0;                                /* toggle clock low */
    & u' w" G  z' c! m# }2 D
  182.         }* r+ ~/ n+ @  W6 A
  183. }  @+ W2 |; R* ^( r7 \

  184. 4 X, ^9 j, |$ C- _/ L! |7 e+ S: _
  185. /************************************************************************/* W$ @5 m/ u: _) _/ w9 k
  186. /* PROCEDURE: Get_Byte                                                                                                        */; V9 J2 [! U7 N* \
  187. /*                                                                                                                                                */# ~; A7 ?% |% u& S7 p, V
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    & \! H; I0 o' R' t  t
  189. /* edge on the SO pin(LSB 1st).                                                                                        */& i' \5 M# r: p: n) B/ n! a
  190. /*                                                                                                                                                */- }% p) H. B. t# s$ E: P
  191. /* Input:                                                                                                                                */7 C4 R/ j+ B! M# Z7 e/ D0 g4 |
  192. /*                SO                                                                                                                                */! F+ |5 p5 S. W( D% H4 C  A
  193. /*                                                                                                                                                */
    0 N* K9 F' D& t! i6 L9 ?+ k# S
  194. /* Output:                                                                                                                                */
    % F, |4 E0 f* S% e& B5 Q+ @
  195. /*                None                                                                                                                        */8 h- L8 O! ?: n# b6 S  g
  196. /************************************************************************/
    3 L1 ~9 w4 H% e! P- b9 h
  197. unsigned char Get_Byte()
    # P# X5 {: a! s; j: Q/ d
  198. {" S5 {* q1 t, W& M" i, l
  199.         unsigned char i = 0, in = 0, temp = 0;2 `+ w$ G9 ]0 q1 E7 {/ K
  200.         for (i = 0; i < 8; i++)
    / C; R- p* h6 Y+ x( K
  201.         {
    , a! p  e. A4 @, U: p$ \
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    9 s: u1 U1 w  C, S$ ?0 \8 u5 P0 Q
  203.                 temp = SO;                        /* save input */
    ( X3 s+ l$ V8 ?( s' E1 Z: S
  204.                 SCK = 1;                        /* toggle clock high */$ x1 X9 f4 M- p% ~8 X
  205.                 if (temp == 1)                        /* check to see if bit is high */
    % v+ j, _; e! r3 N$ J/ S
  206.                         in = in | 0x01;                /* if high, make bit high */. Q2 o, Y% L. L+ @/ \/ _# c- M

  207. ; q4 ~2 e8 j5 j5 n( V' D9 Z* @5 N( A
  208.                 SCK = 0;                        /* toggle clock low */
    6 n0 J* f( s$ i+ K: ?

  209. ) U4 S& L2 [: s3 @1 i, r
  210.         }- {# w6 v* K0 v# y
  211.         return in;: }! C: S% Z9 X& I5 {* ]2 I
  212. }' X; @( \8 H4 }7 @

  213.   a1 K& _7 B* I& g# A. {4 L
  214. /************************************************************************/
    3 @1 @* |$ R/ Q2 u+ {+ g
  215. /* PROCEDURE: Poll_SO                                                                                                        */4 _9 \6 A2 j/ I  s6 J: ^3 r
  216. /*                                                                                                                                                */
    / z# I- `) z# u1 F* \
  217. /* This procedure polls for the SO line during AAI programming                  */6 N7 A) ?, C1 ^# n# F
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/% H- ?$ J! c6 x$ T! H+ G
  219. /* is completed                                                                                                                        */
    1 `9 p+ @; g, M% l+ L
  220. /*                                                                                                                                                */1 g8 K+ f/ |) j
  221. /* Input:                                                                                                                                */$ b+ a. I# R. \, F* f) A4 Q
  222. /*                SO                                                                                                                                */
    2 a" K5 |! @9 z( k# q
  223. /*                                                                                                                                                */
    - u6 v: }' K; r6 z5 h: o4 Y  N3 o
  224. /* Output:                                                                                                                                */9 [* \8 w7 l  ~0 h. I  `6 @. k& E4 W
  225. /*                None                                                                                                                        */
    9 Y  L6 G/ Z$ X5 h
  226. /************************************************************************/- t1 O$ L0 T6 _8 S3 Q
  227. void Poll_SO()
    / F1 }- S  Z; T1 k
  228. {
    + u! K6 ?3 [+ w7 Y( A1 ?( z
  229.         unsigned char temp = 0;; `1 S! x, ]1 _. S) C  C* G9 F: O
  230.         CE_Low();5 F/ o1 u8 m) _- l9 v
  231.     while (temp == 0x00)        /* waste time until not busy */
    3 \& ^- U7 k3 L( k, i4 {+ e/ [
  232.                 temp = SO;
    : O" Q1 Y8 c9 j) U1 e$ {
  233.         CE_High();
    & d4 }& \; I8 h, W% M! i
  234. }4 e, K: ~0 v) ]! ]" k
  235. 8 E" l5 S/ ?' l
  236. /************************************************************************/2 ^, Z' a$ C" }5 H4 k5 N+ y+ m
  237. /* PROCEDURE: CE_High                                                                                                        */
    ' [' ~8 O! X  _; ^6 S' x- c
  238. /*                                                                                                                                                */
      C  K/ x6 r) R: {
  239. /* This procedure set CE = High.                                                                                */! C+ [  P! I: w" `( r  g4 }& X/ w
  240. /*                                                                                                                                                */
    , B; y8 W( g9 z) c. ~" d6 E
  241. /* Input:                                                                                                                                */
    " F# E5 {# [0 c4 t
  242. /*                None                                                                                                                        */
    & K7 Q( @0 e5 J* Q3 w
  243. /*                                                                                                                                                */
      B; T; |+ l& `' p( T' a: f  n
  244. /* Output:                                                                                                                                */  c7 a$ i2 z$ H4 r" \6 J
  245. /*                CE                                                                                                                                */+ F$ t2 F& G: r; n
  246. /*                                                                                                                                                */
    , h/ Q" v( s. M" i
  247. /************************************************************************/
    9 ]7 s5 x' W) h: T
  248. void CE_High() . {# y; ~' \  z  X
  249. {
    - v4 i/ j- a" Z% i. E  Q8 M+ h
  250.         CE = 1;                                /* set CE high */
    4 O( F8 z+ P& {- X6 L" g! [. K
  251. }
    8 F) u& e+ g+ Y( I* ~

  252. 4 y" W8 x& R0 i, }! k
  253. /************************************************************************/
    ! T. x( b. Q4 W( k9 _9 y
  254. /* PROCEDURE: CE_Low                                                                                                        */
    ( s. z! C0 L9 t. u
  255. /*                                                                                                                                                */
    - T1 T3 T# w/ R
  256. /* This procedure drives the CE of the device to low.                                          */- M1 @) \- ^2 I/ Z# u2 d
  257. /*                                                                                                                                                */* ?4 G& z8 ]" u+ m7 K4 p
  258. /* Input:                                                                                                                                */
    " y" Y; X$ W1 g# I* p
  259. /*                None                                                                                                                        */& G5 j) ?6 _& G$ H  [! c  H
  260. /*                                                                                                                                                */! K8 ]/ @7 ?$ N2 Q+ o+ F7 g
  261. /* Output:                                                                                                                                */$ x: d4 ^' F6 Y- K
  262. /*                CE                                                                                                                                */, }( p# a% Z+ N" p) {; H% N
  263. /*                                                                                                                                                */
    / @- Z" L8 }$ ?
  264. /************************************************************************/) O+ `1 i' ^: K, d
  265. void CE_Low() ( Z6 j, ?1 ^# u2 U3 G
  266. {        + ^9 U/ n) y# v/ V1 K0 y3 k
  267.         CE = 0;                                /* clear CE low */* Y1 p0 O" M# L- d. ]# h
  268. }# U' V' L% e2 k8 a" P. e  u
  269. 8 ~+ ]6 h5 ~. k6 Q, [
  270. /************************************************************************/$ D- U7 H1 b- H( z
  271. /* PROCEDURE: Hold()                                                                                                        */
    : M' \6 V" f9 [1 Q/ R5 _. V! E
  272. /*                                                                                                                                                */4 e0 z9 v& s1 g1 u
  273. /* This procedure clears the Hold pin to low.                                                        */
    # h( q8 L2 z3 {& D8 B0 P
  274. /*                                                                                                                                                */) |3 b: f. d- b% Q2 W8 a
  275. /* Input:                                                                                                                                */0 a0 s1 [: H( r8 z- _/ D: P0 M4 X( q
  276. /*                None                                                                                                                        */' L- [) e# k" N5 i$ i
  277. /*                                                                                                                                                */  W8 n' }% \8 _, }4 W( l9 p9 O
  278. /* Output:                                                                                                                                */5 }/ B: P! D8 w/ b& S
  279. /*                Hold                                                                                                                        */
    ; K3 z1 D/ p, E" z
  280. /************************************************************************/$ C4 j# z* U1 S- J7 W
  281. void Hold_Low()  x3 S: b+ d# X& m. j; V/ U
  282. {9 ?( E9 [7 W7 c* n5 Z1 n& M
  283.         Hold = 0;                        /* clear Hold pin */0 [7 u* n- C/ t+ I0 T
  284. }5 n, R; Z: O  ?' D9 V

  285. ( r3 D  b% y/ s5 g2 o5 q% ~
  286. /************************************************************************/8 f& K2 b& J9 E/ q; X  l" Y! [
  287. /* PROCEDURE: Unhold()                                                                                                        */
    ( `, z* |# E- l! j* c) ~0 B
  288. /*                                                                                                                                                */
    2 l7 y( Q$ a4 D  l4 B' `, x
  289. /* This procedure sets the Hold pin to high.                                                        */
    ) U, F) S1 e6 s2 Y5 j
  290. /*                                                                                                                                                */
    7 S  f* y6 O1 S6 ?
  291. /* Input:                                                                                                                                */
    & k1 k/ e. w$ c4 F0 T5 v
  292. /*                None                                                                                                                        */1 V, z) p  e" i6 q4 F
  293. /*                                                                                                                                                */
    0 C: ]7 [* g2 }& s7 i
  294. /* Output:                                                                                                                                */
    8 X7 c9 T4 x+ K; u( s/ L1 `
  295. /*                Hold                                                                                                                        */
    % J+ h- Q2 ]2 m
  296. /************************************************************************/$ e" P- m; [' D) V# w
  297. void Unhold()
    ' k- y) W& D: `" _# u8 R# E
  298. {
    7 q& _& ~& F7 K8 y; ^& w7 p
  299.         Hold = 1;                        /* set Hold pin */% N4 E! C' m# ^2 U8 l: m9 t7 x" g$ W
  300. }" \9 ^  {: x4 u8 U

  301. : K, p* Z) b9 t; N+ Q+ Q5 ~! B8 T
  302. /************************************************************************/
    - h3 k% v3 [! I
  303. /* PROCEDURE: WP()                                                                                                                */
    9 z4 J6 O. e- f- Z7 c
  304. /*                                                                                                                                                */
    - c0 i3 H! M0 q. o, i) a
  305. /* This procedure clears the WP pin to low.                                                                */
      \$ a  p0 m6 L* i3 I; f
  306. /*                                                                                                                                                */* x' u* s. r# H  B, P" z
  307. /* Input:                                                                                                                                */
    4 C3 s4 w" L9 U
  308. /*                None                                                                                                                        */
    3 h' w9 K" @4 g$ F5 m6 i9 n9 x0 ~
  309. /*                                                                                                                                                */
    * k# X( I) R- ~- A( \0 k
  310. /* Output:                                                                                                                                */
    4 V; F) f' m5 x  @" k7 N: j3 I# V
  311. /*                WP                                                                                                                                */1 [' ?% t; q6 c
  312. /************************************************************************/0 ^0 @1 j' q: B  [) _+ z% I3 z4 l8 {& ~$ i
  313. void WP_Low()* X# n  B5 U1 |3 R: y' a
  314. {
    . |3 Q" M0 S5 e8 _4 w
  315.         WP = 0;                                /* clear WP pin */
    - O$ U$ B! [2 a9 o; _* H" m
  316. }, X* V* C% c' x% a' J: X; _

  317. ) ]* `* I7 K* V' _' r
  318. /************************************************************************/$ ~8 V8 i: W7 s. ~" r& r6 e3 ]
  319. /* PROCEDURE: UnWP()                                                                                                        */9 J+ v; t5 W0 s) x& v
  320. /*                                                                                                                                                */
    9 X1 x0 n& ^5 p  ~$ V7 |, `
  321. /* This procedure sets the WP pin to high.                                                                */& ^3 s1 y+ L9 ^- h* ~3 |
  322. /*                                                                                                                                                */
    1 Q; a: F2 `  ?: T9 I4 ]" J
  323. /* Input:                                                                                                                                */% e0 F8 Z0 |0 a$ W! X) V/ P
  324. /*                None                                                                                                                        */" B7 @3 g3 }' c# i- ^7 S* @
  325. /*                                                                                                                                                */* v4 K% c7 t& W9 z& b
  326. /* Output:                                                                                                                                */; }9 N" h  [- J8 f+ D  d+ E  I$ y7 M
  327. /*                WP                                                                                                                                */1 Y% G; g" B2 \" d5 f% f
  328. /************************************************************************/
    * f0 s, Z7 O; i8 \
  329. void UnWP()
      q; _8 Q, B9 m& t. a  j
  330. {
    2 v% v; m- R9 P% p
  331.         WP = 1;                                /* set WP pin *// w; D# C( \/ g
  332. }) p. u) x+ r3 K% k, v8 }! [
  333. - _+ {+ f4 o; ~9 `" g
  334. /************************************************************************/
    : M0 G. c3 `6 F
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    ' ]# @* ?' @& R& e
  336. /*                                                                                                                                                */
      X2 m5 B- g2 [
  337. /* This procedure read the status register and returns the byte.                */% p: m( i- t; q2 a  k: k
  338. /*                                                                                                                                                */
    6 n. }! f5 d2 o, R) M
  339. /* Input:                                                                                                                                */
    # h9 A" Z/ o- ^# Z% K
  340. /*                None                                                                                                                        */
    ' {2 D; z& w' ]3 z+ M
  341. /*                                                                                                                                                */
    + P7 ?) Y# b; M1 P6 w
  342. /* Returns:                                                                                                                                */
    " \; V- o# t/ W) v+ B
  343. /*                byte                                                                                                                        */7 u' g' v: y2 s2 g; T' N1 h3 p
  344. /************************************************************************/
    . m2 U8 i) X- E. u, e! m) ^9 @6 }) Z
  345. unsigned char Read_Status_Register()8 ^1 h& Q& |  [: n
  346. {
    2 }% r/ J% R' o& |  Q/ C- d5 F
  347.         unsigned char byte = 0;! H" Q) h0 H. n  h: D
  348.         CE_Low();                                /* enable device */
    6 `4 o9 V% @" g, _. x, M. y6 J
  349.         Send_Byte(0x05);                /* send RDSR command */
    7 `) t5 p7 ?+ x- I% C
  350.         byte = Get_Byte();                /* receive byte */
    8 j2 f; W- h; b- t
  351.         CE_High();                                /* disable device */
    ) C, U( d! ]+ r  f
  352.         return byte;
    + ^; U" b( p0 u+ L1 J5 R
  353. }0 n& N( j* h3 _9 [) F% u6 J

  354. , c- A6 `' J" L' i( |5 u
  355. /************************************************************************/7 W# t( R( H+ W
  356. /* PROCEDURE: EWSR                                                                                                                */
    % L! ^6 d$ l; k- W0 j
  357. /*                                                                                                                                                */9 ]3 I: ?7 u1 K
  358. /* This procedure Enables Write Status Register.                                                  */8 r# i5 v6 R/ B& M# @0 q' X
  359. /*                                                                                                                                                */# P9 u4 p8 z" H6 }: H3 [
  360. /* Input:                                                                                                                                */
    ( M2 G6 f/ {7 @* X. i' c
  361. /*                None                                                                                                                        */! H7 b* N3 S( T
  362. /*                                                                                                                                                */  O2 y  L2 ]1 u, l3 ^% e
  363. /* Returns:                                                                                                                                */
    / s/ k: j3 P. R- R
  364. /*                Nothing                                                                                                                        */3 e: X" `7 I/ E* `# A% O
  365. /************************************************************************/2 M' }* A' Y% o0 R8 _8 a
  366. void EWSR(), v6 r+ O4 U" D; N! F3 F. t$ a# v
  367. {% R2 @5 J6 Q5 ~( |+ [9 ^5 D5 \
  368.         CE_Low();                                /* enable device */
    3 h$ b! p8 w0 @2 W, x* e
  369.         Send_Byte(0x50);                /* enable writing to the status register */" j  K* q, J- s9 l
  370.         CE_High();                                /* disable device */6 {# p: y0 B; h+ ?
  371. }) u- v. ~  _5 p, l

  372. # {4 a4 t' L+ s4 A& M" |
  373. /************************************************************************/
    * N$ d+ U$ X6 `; l
  374. /* PROCEDURE: WRSR                                                                                                                */8 R' @9 X* E+ f0 k
  375. /*                                                                                                                                                */
      U6 i. k( d0 c- E/ ]
  376. /* This procedure writes a byte to the Status Register.                                        */! u4 _$ P* z  b& P% z
  377. /*                                                                                                                                                */9 I. }  S7 q! e0 W( [
  378. /* Input:                                                                                                                                */5 K) `9 L' p1 [2 k. F
  379. /*                byte                                                                                                                        */# B2 h6 d1 w" n! [
  380. /*                                                                                                                                                */
    2 W. B2 f3 y/ A0 A9 ?) R! h
  381. /* Returns:                                                                                                                                */
    + x' o& M7 N/ ~; J1 F
  382. /*                Nothing                                                                                                                        */
    $ C% I. b$ L6 W  w- B" d. O( \
  383. /************************************************************************/
    9 q# o2 f4 \, ^. R* {& ?
  384. void WRSR(byte)
    5 }8 ~% ?. c( {0 x8 b
  385. {' t* @1 A/ X) s8 t- K# e7 c; l
  386.         CE_Low();                                /* enable device */: b5 z' o6 S7 d2 w
  387.         Send_Byte(0x01);                /* select write to status register */1 a3 _- @/ y7 F- i$ j8 [0 z
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    & F8 i3 r0 V" c4 c
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */; m0 j) F" u" {5 \$ Y+ r
  390.         CE_High();                                /* disable the device */
    ' r6 q; M% U0 S9 K
  391. }
    3 X- H, ~. g. j: D: `& a" s1 j" O

  392. : d* V* H0 o+ a2 s) n1 j% l# c
  393. /************************************************************************/
    $ q" z' G5 F! R( |" X, M3 X& v
  394. /* PROCEDURE: WREN                                                                                                                */
    ( L# Q' Q, U& U* a8 ?' \; z0 v
  395. /*                                                                                                                                                */
    $ x8 i+ ^/ V# f- M, x1 ~4 v
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    + N7 q* @( T. H6 Y5 ]! o
  397. /* to Enables Write Status Register.                                                                        */
    + i2 ~. t7 e: k! m6 y6 |
  398. /*                                                                                                                                                */" X& |( D8 m$ K  H5 S
  399. /* Input:                                                                                                                                */6 `  q! @0 E9 t8 h4 t
  400. /*                None                                                                                                                        */# e/ o- o, J2 y9 I  _- [5 E
  401. /*                                                                                                                                                *// @# D$ i" ^$ x$ L4 [! C- p
  402. /* Returns:                                                                                                                                */
    6 B( B  ]$ W  t4 J+ D7 W6 F
  403. /*                Nothing                                                                                                                        */
    1 I7 c8 r) [, H: X' d+ \
  404. /************************************************************************/3 r* S- H8 w" ]$ g9 F6 h- i( G+ j) |
  405. void WREN()
    5 u( {0 w& s$ u/ T$ |
  406. {. ^6 I6 B/ Y( ?# d' x( ]
  407.         CE_Low();                                /* enable device */
    / ]* `/ n( @2 M- l- `" m
  408.         Send_Byte(0x06);                /* send WREN command */
    8 c  y6 ?  x, K% O& }+ @6 i% x
  409.         CE_High();                                /* disable device */
    7 y5 k  y" {8 y& k7 Q3 R
  410. }
    " Y9 ]6 I+ m2 d' y
  411. 8 f; V9 O0 C  Q7 F# f
  412. /************************************************************************/8 U* V7 W% U# x
  413. /* PROCEDURE: WRDI                                                                                                                */
    2 h" K1 H, v" F
  414. /*                                                                                                                                                */
    ' S4 ^5 x+ P. y% ]4 U
  415. /* This procedure disables the Write Enable Latch.                                                */
    $ I. z( M1 w# M, l+ c" s
  416. /*                                                                                                                                                */$ g* b- J5 h- l( T
  417. /* Input:                                                                                                                                */
    - U9 y0 d9 M; \8 W  e2 o$ I
  418. /*                None                                                                                                                        */! @' ]) K/ X; F  ?/ L9 E
  419. /*                                                                                                                                                */
    * Z6 ]0 O2 C5 R6 O
  420. /* Returns:                                                                                                                                */$ y4 ?+ ~' W4 ?
  421. /*                Nothing                                                                                                                        */
    7 D! [$ j8 q/ \' k, q
  422. /************************************************************************/+ L- q5 d+ X- ]* D1 X! @
  423. void WRDI()
    ( J7 ?7 `: J& Q' N4 P6 S
  424. {" U" G3 P7 D' g. C7 z
  425.         CE_Low();                                /* enable device *// y0 C$ w! H& C. @; N
  426.         Send_Byte(0x04);                /* send WRDI command */
    5 W( v/ Z' T% w' ^& P$ X5 d
  427.         CE_High();                                /* disable device */. m/ k* R# h1 k  g  T
  428. }
    ( l. q' ?% J1 b) D9 m& j+ v

  429. * ^: N" n; [% Y- o; g  g  f1 j
  430. /************************************************************************// E  P2 h4 L- d
  431. /* PROCEDURE: EBSY                                                                                                                */
      P& g* i8 F0 D/ j( m" j9 g
  432. /*                                                                                                                                                */7 p2 ?6 s7 c9 n5 d- W
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */9 H$ n: g0 P0 f
  434. /* programming.                                                                                                                        */
    $ t+ f; S  Z8 {* m9 M3 r* W
  435. /*                                                                                                                                                */8 u! J( l3 \* M
  436. /* Input:                                                                                                                                */
    - M: M) u$ r/ E; S' L
  437. /*                None                                                                                                                        */
    1 l+ k+ ?! A0 ]5 u: o+ O' \5 S
  438. /*                                                                                                                                                */
    # _' |' h7 z4 m8 ]
  439. /* Returns:                                                                                                                                */
    ( x5 _( g  T3 K3 i& E
  440. /*                Nothing                                                                                                                        */
    ! \( ]' o/ W/ y& \
  441. /************************************************************************/5 b1 A8 I1 T7 b3 P+ F; d( H
  442. void EBSY()
    & F1 W8 I7 s& E4 C" Q
  443. {1 }% p8 x! f5 {. F9 Z
  444.         CE_Low();                                /* enable device */( M  h! C9 V0 ]; e- P
  445.         Send_Byte(0x70);                /* send EBSY command */
    - }; `3 H0 K2 e7 V. o% K, @9 D
  446.         CE_High();                                /* disable device */
    + ~1 E6 b+ u3 x8 F. `2 f
  447. }
    . }8 O% ?, ^# o1 O8 C
  448. 6 m7 |" |* d: b4 l( e% |* z$ H) t
  449. /************************************************************************/
    / s' K$ h9 D% w, v
  450. /* PROCEDURE: DBSY                                                                                                                */
    7 C4 P9 N6 w: c! F# W
  451. /*                                                                                                                                                */2 Q6 _5 t4 {# C9 A" w) F0 a" e
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */+ ?5 h8 R4 G8 v) d  p6 p) m
  453. /* programming.                                                                                                                        */; b+ e' a! g: W: X  [4 D
  454. /*                                                                                                                                                */5 y0 m4 _3 w7 s% d
  455. /* Input:                                                                                                                                */7 h$ I4 c3 Y8 n3 v7 y( F4 [4 i
  456. /*                None                                                                                                                        */
    ; j1 i: C0 W3 t; A: ~
  457. /*                                                                                                                                                */
    ' B9 z( c# g" B! j+ H$ k: k) Q
  458. /* Returns:                                                                                                                                */
    ' A7 o' q. |$ h$ k
  459. /*                Nothing                                                                                                                        */
    * R% w5 t6 N" A5 M
  460. /************************************************************************/
    , j, i" s/ U" D% ?8 p
  461. void DBSY()) t! o. r' [9 s) b$ S- X
  462. {
    " ]# Z0 M5 r3 h
  463.         CE_Low();                                /* enable device */" d' ~3 q/ E" {1 G/ D" l  ^
  464.         Send_Byte(0x80);                /* send DBSY command */
    4 t, y4 C, j: _2 a; l) B
  465.         CE_High();                                /* disable device */  `# p( f1 H' Z5 o3 r
  466. }' ?6 L0 K& x; A  A4 [: x

  467. 6 z: |9 J. C* x3 N' \
  468. /************************************************************************/% e5 C5 \) I2 [0 r' S. @: X4 I
  469. /* PROCEDURE: Read_ID                                                                                                        */: @" G. c- k2 v
  470. /*                                                                                                                                                */
    3 e9 }7 t* ], v) ~' E* L
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */1 q- {- u8 `5 U
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */) @" Y( v: b6 u5 M  w/ x6 C
  473. /* It is up to the user to give the last byte ID_addr to determine      */0 U. D$ L: y8 }% z
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    3 `1 P( C/ M* ~4 C9 M
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    + \4 x# T$ e/ ~5 j* s
  476. /* variable byte.                                                                                                                */- D2 o4 b$ O8 m5 b( i
  477. /*                                                                                                                                                */, d8 P" v! @5 \# I- s
  478. /* Input:                                                                                                                                */
    9 W0 r) O8 A5 ?1 H' [
  479. /*                ID_addr                                                                                                                        */
    0 P. I  |: M. u% p* M6 Y2 |
  480. /*                                                                                                                                                */* e3 o' {. [5 ]
  481. /* Returns:                                                                                                                                */
    6 e2 T( |7 n+ W$ |2 L& `$ O4 x
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */4 X1 c+ l$ H" A1 m4 \. ?$ w
  483. /*                                                                                                                                                */8 q) A. ^, U& }' U% r( V% K
  484. /************************************************************************/1 T/ A) y& T+ ~/ P, q& F
  485. unsigned char Read_ID(ID_addr)% U# B1 v2 r, S- K! B6 u7 g9 y
  486. {
    6 }9 J1 r- a4 a" m* G( a* K  a5 x
  487.         unsigned char byte;
    2 F. {+ k3 D* {' R
  488.         CE_Low();                                /* enable device */
    - T4 I& q' Q: B, B6 O& j
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) *// n$ N- }* R3 S3 o5 N8 C
  490.     Send_Byte(0x00);                /* send address */
    9 Y. A! T( |7 Z  E8 [9 d% |
  491.         Send_Byte(0x00);                /* send address */
    # ?# U2 N" _7 ^
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    3 S& r5 u& m  k, T- N# N
  493.         byte = Get_Byte();                /* receive byte */* b: w/ ]1 B$ i* I1 Z; `2 y
  494.         CE_High();                                /* disable device */' B" d6 w9 R8 w
  495.         return byte;
    # V6 ?2 N, A& v
  496. }( ?* o. N: ^1 ~: T& W9 I
  497. ; N4 s, v9 K- F
  498. /************************************************************************/" P9 ~5 X! u+ [
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */: t9 p0 N/ v: E
  500. /*                                                                                                                                                */- y& T( ^& a; M# n
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */* h7 g; |7 I; E  k( L8 q
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    ! E+ u- b6 t0 }
  503. /* Please see the product datasheet for details.                                                  */# P/ M/ a$ ^/ v5 t: ^
  504. /*                                                                                                                                                */: i  e' S9 X& w7 V2 \2 E8 {
  505. /* Input:                                                                                                                                */$ G% F& i1 l9 A; a2 f
  506. /*                None                                                                                                                        */
    7 C. I( _, H, B, F0 C  q/ B
  507. /*                                                                                                                                                */
    % ]" Q0 A1 t3 y. o2 _0 H! o9 L! y* L( i
  508. /* Returns:                                                                                                                                */  _4 O- |: y! o; m5 P& J) T5 y
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */4 c! v/ w# K5 _. c, w1 ~9 e
  510. /*                 and Device ID (8Eh)                                                                                        */
    , _( t, P$ u7 S# g
  511. /*                                                                                                                                                */1 e# N' X+ H" m8 O* w$ K! `* A
  512. /************************************************************************/! |7 h! i4 v; V  O6 y7 X
  513. unsigned long Jedec_ID_Read()
    " \& l, S" N" x# T. v0 P
  514. {
    9 D$ L1 |" T. V6 r. Q: \
  515.         unsigned long temp;
    7 \# G; g( \4 N+ Q6 s
  516.        
    5 g8 r" I  @2 K5 ~
  517.         temp = 0;
    3 e$ B. D: D! ~. q- D# _

  518. . h8 ]7 d- y) f0 {
  519.         CE_Low();                                        /* enable device */& U( }1 ^2 @, r6 ?
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */; e7 M4 q  a4 C$ G5 a2 Z
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */" M& X' T: U1 |+ n) J1 u* \' G' {* @) B
  522.         temp = (temp | Get_Byte()) << 8;        0 k; m: E3 _4 T9 a' R/ u! \
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */% W, N% ~2 R1 y- S6 A: z
  524.         CE_High();                                                        /* disable device */, t4 k/ P" X! |9 u6 W6 x

  525. ! Y' r0 g$ L1 X- j
  526.         return temp;- b4 H  b2 f6 w0 ^( K9 B, r- B' }
  527. }
    + j! ?! H) x3 E/ ?4 t7 s% R0 _
  528. 9 j" F4 N5 D9 o" Z/ i
  529. /************************************************************************/
    1 d) P( D( g$ C9 ^
  530. /* PROCEDURE:        Read                                                                                                        */1 ?- d' R3 Y! f1 D) B
  531. /*                                                                                                                                                */                0 C% [4 q, t1 T: `4 {& g) L
  532. /* This procedure reads one address of the device.  It will return the         */9 x- a) m' R8 V
  533. /* byte read in variable byte.                                                                                        */
    0 ^4 X+ e. H* s# L4 m
  534. /*                                                                                                                                                */
    , X0 ^, P3 q1 x- X* I. K% _( I8 U
  535. /*                                                                                                                                                */3 n3 i+ T) g1 Y3 @0 n
  536. /*                                                                                                                                                */5 n/ D1 x7 Q3 k* L# D& A! f$ u
  537. /* Input:                                                                                                                                */5 k% y* Y4 P4 e
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    ; M' }" ~7 c. J' f- z- n
  539. /*                                                                                                                                      */
    - }/ v; j' c2 T9 W
  540. /*                                                                                                                                                */! {  y" E7 ^1 |4 u  S) M
  541. /* Returns:                                                                                                                                */; j. t; R) U: B
  542. /*                byte                                                                                                                        */
    % z7 ^- `. r' T, d8 C
  543. /*                                                                                                                                                */1 ~: z7 L' W; u3 t. c
  544. /************************************************************************/
    # S9 a2 o6 ~* \7 }+ L
  545. unsigned char Read(unsigned long Dst) & ^9 t) I% `# }) |- m$ z9 N4 E" M
  546. {
    ; O9 q3 D0 k# ~* m. e7 V
  547.         unsigned char byte = 0;       
    9 T& g5 k5 e& f/ i4 n1 t! i
  548. ) a1 K) u) S  v. _, J0 p8 m! a+ M
  549.         CE_Low();                                /* enable device */" f! Y- s( b9 Z# f8 [( ~  ]
  550.         Send_Byte(0x03);                 /* read command */9 j1 a! l! R; `2 _. g$ K5 S' B% p  E
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */* D- z- T1 \1 Q
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));! W2 S9 m; ~2 `, K# n
  553.         Send_Byte(Dst & 0xFF);
    # m; n% \* _' F' j4 m, c
  554.         byte = Get_Byte();9 O1 h) V5 r4 A% c- \  w+ I
  555.         CE_High();                                /* disable device */1 B. i; M; \9 i! r4 p) }$ F4 P" [
  556.         return byte;                        /* return one byte read */
    + a1 u* z- c) @6 [: Z% _0 l
  557. }
    ! u: {7 d! ]9 T5 R
  558. & i5 Y9 ?. F- j( M* g2 a! [! Q( L* y
  559. /************************************************************************/
      e8 d7 v" L/ j! Y; V% K! F- `
  560. /* PROCEDURE:        Read_Cont                                                                                                */1 J% b2 F, H4 ~2 M* ^: s0 S
  561. /*                                                                                                                                                */                6 r9 K# `5 I4 ]: @% M, p; T
  562. /* This procedure reads multiple addresses of the device and stores                */& T3 u% ?; w' g7 {' a3 W( J
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/& P5 |! x! z- q& e. [
  564. /*                                                                                                                                                */
    9 j/ ?2 R- B. D% A% {" B+ n# S6 f
  565. /* Input:                                                                                                                                */1 C6 {# [# w8 `* `: [
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */8 W1 v5 J, s1 c' R% D* c
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
      @6 G4 e1 F+ A
  568. /*                                                                                                                                                */
    * q! X" o- K' ~, c6 I! @
  569. /* Returns:                                                                                                                                */
    " S' |( J1 o8 W! g/ ~& |7 X8 o
  570. /*                Nothing                                                                                                                        *// b5 o1 P6 p: R7 n
  571. /*                                                                                                                                                */; i) j, S3 l7 D& c1 a0 i5 p. ]
  572. /************************************************************************/
    : `$ T0 {% X! \( P1 D# I5 y
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)& W/ y$ q* m% |, l1 K" _
  574. {7 S4 s& i6 T' {9 `. A) W) j
  575.         unsigned long i = 0;
    , M% i/ [+ Y0 ]7 f
  576.         CE_Low();                                        /* enable device */
    3 y7 O% v% @- t
  577.         Send_Byte(0x03);                         /* read command */
    8 G# j5 S9 ^% K. C; u, E0 n/ D% q
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */4 D7 x; \% q$ R: X+ C8 U) h- J
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    . }6 A& f2 j( k- v* f
  580.         Send_Byte(Dst & 0xFF);
    6 l2 w7 u( ]4 j
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    7 z5 m$ B  J  f. i
  582.         {' B8 y1 D% P3 t& s1 u: i( {  i. j- q
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    + k  n( h" _: N( ^; `% j  g' z( L
  584.         }
    ' k8 k. A" V% \+ P
  585.         CE_High();                                        /* disable device */7 {& F/ e+ T% [) ?# x. z
  586. 0 G& b1 y8 R! Z& Z+ }( ^, @
  587. }
    $ D; a8 a! ^- v0 D# F5 v$ d

  588. & \* x! v( d. B
  589. /************************************************************************/
    3 u  {/ x. t' J! H) n. X: N5 A
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    ) X1 h: x$ u) H5 |* H
  591. /*                                                                                                                                                */               
    . `2 J5 c8 L; o# C+ ]# @* e8 T* Z
  592. /* This procedure reads one address of the device.  It will return the         */
    ) K- E: b7 ?( {# p9 H, ^
  593. /* byte read in variable byte.                                                                                        */" s* a' u( Y& G
  594. /*                                                                                                                                                */' Q* M- D% c" y2 o: z3 X
  595. /*                                                                                                                                                */1 F& q" e! j. A+ Q
  596. /*                                                                                                                                                */' ?1 e% O$ Q3 `0 ?* z
  597. /* Input:                                                                                                                                */' H/ T$ p, a) y0 M& y
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */& h9 m; A  X: m* D3 n3 V% [
  599. /*                                                                                                                                      */
    3 R8 i, X, P, i  o# F7 J
  600. /*                                                                                                                                                */& v6 v; Q7 d- |* M, E) @; r+ r! m! g
  601. /* Returns:                                                                                                                                */
    , J  I* W( ~" W7 w; _: g7 N8 g. ?
  602. /*                byte                                                                                                                        */
    4 p. g& k2 ^! L0 H8 G' f( h
  603. /*                                                                                                                                                */$ z) b) D/ w: l: l* b
  604. /************************************************************************/+ A* k( |6 [4 D, c6 u
  605. unsigned char HighSpeed_Read(unsigned long Dst) + i4 e, I, D# e! C+ q
  606. {( ^  ]  R$ q7 A0 @& K
  607.         unsigned char byte = 0;        3 G: L0 v+ o) L( ~" x9 ?: q$ f
  608. ; [  _/ N9 ~& G6 Q. |; `  R
  609.         CE_Low();                                /* enable device */
    + M% W# W8 `4 G* Y4 U; W& {
  610.         Send_Byte(0x0B);                 /* read command */4 ?. m' w3 i# n" }! v& E; e% z
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    $ y$ k) V* w9 R$ X, ^# `3 L
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    3 m8 N/ a" b0 s7 O' |) N
  613.         Send_Byte(Dst & 0xFF);
    , p- l3 n2 t# ?
  614.         Send_Byte(0xFF);                /*dummy byte*/
    * {' t! W' t, q& e. r
  615.         byte = Get_Byte();
    4 z4 Y$ J0 b3 U& f
  616.         CE_High();                                /* disable device */
    ) [$ w6 l2 \* t7 j6 X4 g
  617.         return byte;                        /* return one byte read */4 x' ]( l8 h% j3 b
  618. }: c  a$ T( n+ s; E$ t

  619. 6 g2 e4 A! v9 {4 g
  620. /************************************************************************/
    ; F9 v  \  _8 m! V( ]1 c
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    5 C" C( o6 B, Q+ V  A, E
  622. /*                                                                                                                                                */                # u: _9 h. D* R& F4 t: [7 g- m' _- O
  623. /* This procedure reads multiple addresses of the device and stores                */8 |* l6 y( N: ?/ G' N! D
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    5 b8 I" b' c! S( \, U& g% L
  625. /*                                                                                                                                                */# x! M+ [& q$ [4 w$ J
  626. /* Input:                                                                                                                                */
    , N: ]7 m% `9 r  A9 [
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    7 ]0 X5 Z; m; s& ^0 |+ f' m4 ?
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */( M, n8 x, ?" h9 T# }
  629. /*                                                                                                                                                */
    ; u* ^( j1 z0 {2 Z% F% t% Q7 g
  630. /* Returns:                                                                                                                                */3 q, i: k/ N0 y- |* C1 M
  631. /*                Nothing                                                                                                                        */
    & B$ x+ p# m' C" p% R) W
  632. /*                                                                                                                                                */! f6 i( l+ O. v7 g( B) b
  633. /************************************************************************/
    ( D$ X5 i7 D; V1 |) l" v# b
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)4 U$ K0 t" p1 S
  635. {
    : j/ t) M4 b" Y$ j
  636.         unsigned long i = 0;
    2 N( A+ `6 R" Q! c7 j& C8 v, M8 a- M1 y
  637.         CE_Low();                                        /* enable device */
    , n! k+ ^- u* L% D5 X9 }: [1 g) M2 o
  638.         Send_Byte(0x0B);                         /* read command */
    2 o, U* e5 C+ t4 q2 Y1 ^
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ! g. T! |/ V) X6 O4 f# I( W
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    / v( \/ a3 \# d+ Y9 P8 p
  641.         Send_Byte(Dst & 0xFF);
    $ n% A2 I! `& A6 p( W
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    3 x+ `/ Y* z, z% h" C9 o
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    4 y+ ]- }3 F; o. W
  644.         {" G2 q& ?& C, A  I; Q) |
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */- p' A  V7 ?+ h* d& k- m9 R
  646.         }5 O% H& W$ a* y7 v5 J, b
  647.         CE_High();                                /* disable device */
    % H$ q  E0 B9 `; D3 f; p8 a+ h
  648. }
    # Q6 y8 G5 V1 o) y+ _: u

  649. % S; m) x% H: q
  650. /************************************************************************/
    % K3 Q( b2 f1 k: {9 o5 t4 q
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    " A- ?/ U  R; ~6 b# |( T5 i1 s" t( Y
  652. /*                                                                                                                                                */
    , [3 _  g: U$ n) s3 x
  653. /* This procedure programs one address of the device.                                        */3 u9 p- y/ W6 r6 m+ Z- |; R8 n
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    4 D  i7 i; E% X
  655. /* block protected.                                                                                                                */
    9 d5 B5 e$ |" R- W9 [8 X8 g5 [
  656. /*                                                                                                                                                */
    & O( @% x, g/ y2 ^+ j( b
  657. /*                                                                                                                                                */5 M2 X& H; ]* P4 c/ |
  658. /*                                                                                                                                                */
    # \+ O) Y! X6 z' O8 E& q
  659. /* Input:                                                                                                                                */
    : A' r6 W0 a6 [1 V7 l  H6 ]. }
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    " I, d0 E: p& S
  661. /*                byte:                byte to be programmed                                                                */
    3 C" w: L4 h0 m4 F4 r4 q8 c
  662. /*                                                                                                                                      */
    " |# T0 N; C! e% m' h8 V( C
  663. /*                                                                                                                                                */
    7 \, p1 m' H4 O; o; `  L/ |3 o/ Z7 u
  664. /* Returns:                                                                                                                                */
    ) R* g; v  ^8 e, @
  665. /*                Nothing                                                                                                                        */- l! t1 l. @  t  |- G8 a
  666. /*                                                                                                                                                */7 ^+ a2 j0 X; W7 M5 Q/ k: n7 `
  667. /************************************************************************/( {2 K" k( w9 e$ j, s  i2 A! U( `: y1 }
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    * {( p" Y1 k5 M6 y( G
  669. {
    , o# w1 @" M6 q) A* u
  670.         CE_Low();                                        /* enable device */* K6 b0 }5 y8 p/ L+ ~
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    " c+ e4 W/ i3 L" f
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    $ A  l$ |. O5 t" U' y4 s
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    + p- y0 j0 e( P  m3 Z* p" \
  674.         Send_Byte(Dst & 0xFF);
    2 i3 F+ w! V  |! @( M' M
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    ' h* T7 ?+ b. f6 A! |) }+ K
  676.         CE_High();                                        /* disable device */
    3 X( ^+ }3 ?2 C" R
  677. }
    ! L$ `% }% i( F' o9 J: |
  678. ) W) c& z( l0 R
  679. /************************************************************************/
      G& U0 |, K$ ?$ ^0 f
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */; w. [$ `6 n- c' k4 u* t. M' q
  681. /*                                                                                                                                                */
    ) J7 X" O# p1 U8 f3 _1 _
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/! Z3 ]* w/ `1 D. X0 u8 {* O
  683. /* the device:  1st data byte will be programmed into the initial                 */
    . T6 ]4 K: x3 m4 ]$ V5 u
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    3 V& p' t% A4 F, F: L
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    & w+ `: X3 \1 P, R3 X
  686. /* is used to to start the AAI process.  It should be followed by                 */
    " Y5 w% B% `4 L) r# i7 b
  687. /* Auto_Add_IncB.                                                                                                                */
    , m+ J3 w( J1 X' y" ~7 [9 ]" U
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    5 A/ d6 M! e0 w
  689. /*                                block protected.                                                                                */. T9 Z- o2 l) W0 F( s6 \5 Q4 v
  690. /*                                                                                                                                                */" D* b8 V' \! t! c
  691. /*                                                                                                                                                */  k+ y+ ~6 Z& @, i  k& u" s8 F
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */- x0 V( X+ ?! S7 t
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */: h6 [$ U; n  |) O  u( h' N
  694. /*         unless AAI is programming the last address or last address of                */
    8 i8 @# ^  V* O: t
  695. /*          unprotected block, which automatically exits AAI mode.                                */6 X6 b' _, @4 k( F, n
  696. /*                                                                                                                                                */6 }. L$ L0 t0 a, ~( k/ D
  697. /* Input:                                                                                                                                */
    $ L$ E9 H; O! z1 d0 s
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ' j# [4 c3 u! R( m" X
  699. /*                byte1:                1st byte to be programmed                                                        */6 B* c4 E# q8 i6 K6 ^1 j7 i
  700. /*      byte1:                2nd byte to be programmed                                                        */" \" i/ O3 k" T7 y$ g/ n9 A3 I
  701. /*                                                                                                                                                */: P. A9 s9 j3 T$ x) X
  702. /* Returns:                                                                                                                                */" }; J! L9 g4 }! k* {( b
  703. /*                Nothing                                                                                                                        */
    6 V3 l" E* j5 }) T$ M6 |
  704. /*                                                                                                                                                */! Y; c* |' c8 ~8 T% P4 e7 ]' O
  705. /************************************************************************/4 U; e7 V& b6 m2 F' p
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2); h+ B: X* f! y6 G- @! q4 {
  707. {
    6 q) f/ X- O1 I" y' ^; ~" r
  708.         CE_Low();                                        /* enable device */
    ' L& {. u3 ]( I# I6 q: k  E* J% T
  709.         Send_Byte(0xAD);                        /* send AAI command */
    & E, X: s/ k# Q
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    9 e, f6 U# M+ q' ]7 Y; o
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    3 C5 b: H& E$ @" m5 s. c) w2 \
  712.         Send_Byte(Dst & 0xFF);
    / L& h4 t) c! I% t" I4 t
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        " ~2 `, M" E* z
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ; K3 X( j: v# n. k
  715.         CE_High();                                        /* disable device */
    . y3 m- F! Y( c/ G8 J
  716. }/ I; f' o+ J9 H  o7 O

  717. ! w* Y2 @; `0 A8 e( s
  718. /************************************************************************/
      v7 [- V9 j: [) r
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */# N6 x: ^; w* b6 X5 W
  720. /*                                                                                                                                                */  M" q0 ]: w9 @% u* j$ f, @" }, L
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/0 e  K, X6 J8 N
  722. /* the device:  1st data byte will be programmed into the initial                 */$ B+ h0 k% j, t; I- P7 e  U
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */+ ^7 y0 E$ g" J% z
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */' V2 r7 D, ~2 X6 X
  725. /* is used after Auto_Address_IncA.                                                                                */
    5 {' l4 _3 v; e5 a! k- b
  726. /* Assumption:  Address being programmed is already erased and is NOT        */! t; j3 g9 A' G% {: ?1 g; H
  727. /*                                block protected.                                                                                */; s! ^$ }) Q% Y( q! D, i2 n
  728. /*                                                                                                                                                */
    5 d* O/ m8 m* l9 D% J+ [
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ! B, G' m2 `3 b5 @0 h* B0 L
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */; l' i1 e+ J8 J3 v$ @. j  ?, C& Z! f
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    * h! G5 q9 n9 H  w/ q  d
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    8 @7 _+ k6 C: `9 R
  733. /*         last address of unprotected block, which automatically exits                 */; |. T5 Z, I% D
  734. /*         AAI mode.                                                                                                                        */2 r! n# f: i0 }6 k
  735. /*                                                                                                                                                */# a/ T  m7 L/ \
  736. /* Input:                                                                                                                                */) A% K1 V6 j* q% \6 }
  737. /*                                                                                                                                                */4 s7 K) y% ?: ~0 V1 I9 c
  738. /*                byte1:                1st byte to be programmed                                                        */0 a$ X# t# l* m% @
  739. /*                byte2:                2nd byte to be programmed                                                        */
    : q# p% v6 d' D# X- U
  740. /*                                                                                                                                      */
    + G3 @# {" c) U" P2 t9 A' d
  741. /*                                                                                                                                                */- a1 x! y) h! S. N! w( b( w& `1 n6 r
  742. /* Returns:                                                                                                                                */0 U/ T- Y1 a& {7 Z2 _6 N
  743. /*                Nothing                                                                                                                        */4 [  J0 p+ D+ A
  744. /*                                                                                                                                                */# `# R  r. A$ i% i8 y  D7 C
  745. /************************************************************************// q) S& [  p1 @6 W$ y
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    2 w4 m# }1 {) a0 D  R
  747. {7 ?+ R; O9 c# R8 m/ _9 ?. n
  748.         CE_Low();                                        /* enable device */  I3 n+ R! p1 J! ?. L, x3 f3 @
  749.         Send_Byte(0xAD);                        /* send AAI command */
    : V! N4 ^* ?2 f5 ?. z1 O
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    - O+ B6 B2 Y, p
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ) F/ o9 c, |$ `" q+ X5 f
  752.         CE_High();                                        /* disable device */3 _% d3 ]+ C9 R/ X& O3 d
  753. }
    3 Q. w. k: |, Z+ q# h
  754. 5 {% N2 @7 W6 @/ J& w' K& @+ y
  755. /************************************************************************/
    / c7 L; q9 R6 c1 Y
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    " P/ G$ P5 P, S3 |/ R: h5 c
  757. /*                                                                                                                                                */- R1 }! a; W* |6 ]4 b) ~5 v
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */$ K8 m, h2 s; i5 ?2 n% ^
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */" p+ \! S) }) F+ j8 q1 a0 F
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    1 ^' D* H/ Z2 n2 b0 |  |2 Q4 ^
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */+ T" H3 m0 o1 a9 B# x; h9 K, M
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */. s8 o7 g% K( }9 E9 p; z2 D- r8 z6 j
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    0 a3 |3 x% @, A& I7 H; Y
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */7 R# @: U! P" n* c1 y8 Z6 ~* Z
  765. /* Assumption:  Address being programmed is already erased and is NOT        */  F& z# [& l" E) f& e; G
  766. /*                                block protected.                                                                                */+ q, y. e- i2 u. P5 W
  767. /*                                                                                                                                                */
    ) B/ ]* U) K3 ~, ]3 D& O
  768. /*                                                                                                                                                */
    5 ~( {8 |0 n+ R3 K2 v) p
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */8 O" q1 ]/ T1 q6 ^/ ]
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */0 k# _: V' r0 b+ S8 O- m3 {
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */+ s0 S) `( ~  z& v+ t6 o) X6 J
  772. /*          to exit AAI mode unless AAI is programming the last address or                */* v5 D$ ^, s' y, q
  773. /*         last address of unprotected block, which automatically exits                 */7 h: y( \# Y4 s( J+ K+ S
  774. /*         AAI mode.                                                                                                                        */$ V; w4 D$ h0 k% j( X
  775. /*                                                                                                                                                */4 e/ }  i" r, r# L( i7 h
  776. /* Input:                                                                                                                                */4 Y! p4 B+ X  V) ?' E7 O5 x- |6 K
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */1 F- h* P0 o% @/ a% e
  778. /*                byte1:                1st byte to be programmed                                                        */6 V& K' ~0 x, @5 ~* f
  779. /*      byte1:                2nd byte to be programmed                                                        */! l  M6 V9 L  x) d4 O
  780. /*                                                                                                                                                */
    ' P. V( B3 N6 ?/ ?" C' A
  781. /* Returns:                                                                                                                                */
      R% i5 c0 g! U4 b" z- \6 q/ t8 s
  782. /*                Nothing                                                                                                                        */) n% K! Y4 n# Z: E* e- u; v
  783. /*                                                                                                                                                */* o) r8 i. C- `0 t5 G' k
  784. /************************************************************************/
    ) }& S+ L) G5 s. X5 ?$ B
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ! A5 }6 G0 e, {( P* [- H& M
  786. {6 V' }3 l2 e' ?$ j1 f4 b/ i
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    + v/ K* z5 E% I& [1 m5 v2 A* C$ x

  788. , Z5 a) d! s; B' E
  789.         CE_Low();                                        /* enable device */
    $ l" N& ?5 ^* y. q
  790.         Send_Byte(0xAD);                        /* send AAI command */
    4 R( a7 j; @. w  C$ }& Q# f6 f
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */% F8 `6 I" |* X8 r; j3 }7 d
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ; v6 R0 f# u: u/ t6 }- k. T# C
  793.         Send_Byte(Dst & 0xFF);
    ) g8 V7 b% D6 i
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    + p. @/ |3 M3 V* Y* C( a
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */( Z' o# c% L) F9 w3 D- A5 i$ J
  796.         CE_High();                                        /* disable device */
    3 o+ a& T. w" u) H
  797.        
    + k& y7 A/ }  B: E' h
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
      o2 ?7 Y1 l9 T7 w9 [8 X' T& {

  799. ) u9 F1 R+ C; o: Z3 Q
  800. }1 F' g" T- I/ R3 j3 u: Z

  801. 2 v% Q2 X% \+ e$ W
  802. /************************************************************************/
    * n- C  q1 {; P8 o( H& ]# c( y
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    , x4 p/ z7 |& Q2 x5 M
  804. /*                                                                                                                                                */
    ; o( a: u# |: s! o9 X+ D
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */5 C! F  U  y/ |# B! q' e
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    0 E# r1 _/ N- @# T6 I  G) j" F: R
  807. /* AAI programmming is completed.  It programs consecutive addresses of */0 n3 v! s* J: P* f7 B3 Y. h5 \% U5 w
  808. /* the device.  The 1st data byte will be programmed into the initial   */* e( M; g4 a5 _! K; }! T% O9 _
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */, c7 q+ y9 x2 B0 \& v( f
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */  h' @0 ]8 ]) k2 W4 f, F" ~3 r
  811. /* used after Auto_Address_IncA.                                                                                */4 x- U4 ]6 H; m' g
  812. /* Assumption:  Address being programmed is already erased and is NOT        */7 k) `# Y" }2 X' t# ]% X# C
  813. /*                                block protected.                                                                                */
    ; b# D8 i8 `$ Z- s  b
  814. /*                                                                                                                                                */
    7 N( Q5 L! l% D
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    2 z8 {& ~9 F! Z3 _  z. b
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */+ s, k$ B( a: ?: Z8 x+ y% u
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ; P1 Z# T1 _0 y" H  [* ?( _) l
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    % `1 t9 E9 y* C) s! l
  819. /*         last address of unprotected block, which automatically exits                 */$ J8 Q' v# A, M, w& t
  820. /*         AAI mode.                                                                                                                        */, Z" }1 g/ l, h
  821. /*                                                                                                                                                */
    # D4 i8 V! r( F1 {9 M! i: \' Z
  822. /* Input:                                                                                                                                */: U* ^% U3 S4 Y. j
  823. /*                                                                                                                                                */
    8 y, z: e. P! ~/ G# i# i& p' F
  824. /*                byte1:                1st byte to be programmed                                                        */
    4 N6 ?/ m; M, X6 x: \) K) v
  825. /*                byte2:                2nd byte to be programmed                                                        */, w6 u4 I5 O) P, p
  826. /*                                                                                                                                      */# e  S1 {! d5 l' Q2 v& g7 Z* _
  827. /*                                                                                                                                                */0 i: s- O! w8 a% M
  828. /* Returns:                                                                                                                                */
    & _/ G: n2 o( r3 [3 ^
  829. /*                Nothing                                                                                                                        */9 r3 J; d9 i0 C" e; ^! P
  830. /*                                                                                                                                                */, p8 s. r5 i, p2 W& Z  X$ K
  831. /************************************************************************/+ t, L5 ]# S+ }7 l6 @. Q. w
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)+ G# v$ g: Q1 I# `5 ?9 f
  833. {
    - i0 B$ |7 Y- a2 T( R) u5 y
  834.         CE_Low();                                /* enable device */
    + \9 f" z# @, l' v
  835.         Send_Byte(0xAD);                /* send AAI command */
    * {  u/ B+ r! B8 ?0 h1 N
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    # f9 a: ?9 `5 a8 E* q
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    : U9 @7 m& O/ Y; g+ T
  838.         CE_High();                                /* disable device */
    0 \. a" x9 F0 O0 s& V5 B9 e
  839. 1 `% w: f4 }* q' m0 r! c
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    8 T" I! a/ n1 T& o& f
  841. 9 s. i9 e+ n& [) e" P% K
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    % l2 K9 r0 ?' F! w" @' x
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    - P# q# O3 |2 B. d+ f
  844. }; a' U# ^7 K' d- T7 L. V

  845. # p' c3 i! m/ }0 V3 K5 m
  846. /************************************************************************/8 E; q1 Q+ Z5 v" f4 M
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    & b; D' L3 a' c6 K" C
  848. /*                                                                                                                                                */9 g. ^, k: [$ F# i8 S( d
  849. /* This procedure erases the entire Chip.                                                                */
    4 Q/ p$ c# \  \; h! B3 _" }% N
  850. /*                                                                                                                                                */
    + r. a/ B; A0 V
  851. /* Input:                                                                                                                                */9 m% m* r+ [; {2 E* y
  852. /*                None                                                                                                                        */
    3 o! g% G& p) ?
  853. /*                                                                                                                                                */+ G; s$ K" F' o$ t
  854. /* Returns:                                                                                                                                */& ?+ G, d" v: t) E
  855. /*                Nothing                                                                                                                        */
    % n  h4 e$ J( Q2 }& c! W
  856. /************************************************************************/; J% o; Z3 e: r. h- ]7 {7 {
  857. void Chip_Erase()! V* A; u8 y/ x+ Y; r4 S! s4 P
  858. {                                                & N  j/ H- \0 `  Z3 S8 b
  859.         CE_Low();                                /* enable device */
    & O2 c* D" q0 U+ a2 }8 ^- A6 {
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */+ B0 M* Z: G' Y& u3 |) z
  861.         CE_High();                                /* disable device */, ?- c' I" x+ B% L7 z4 O# f: [
  862. }
    7 i# z  i5 o1 ~, {: @$ @; n: N7 {" O

  863. " A% o2 E. R. z+ y7 v
  864. /************************************************************************/
    8 r( h. Y/ C% `) n3 n* l, l3 X
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    ' m; ^0 n. v' N2 S! |$ e3 H
  866. /*                                                                                                                                                */) D- d. \+ F4 p+ \+ C3 o
  867. /* This procedure Sector Erases the Chip.                                                                */% A6 Q$ \  }( i$ c
  868. /*                                                                                                                                                */
    5 y' D% z8 S' Q
  869. /* Input:                                                                                                                                */: O$ j( s/ F5 P) x4 }9 N" @  P
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ) X* `# o, b/ b& @0 t
  871. /*                                                                                                                                                */
    / T2 ]$ ?% `4 S) g8 L) k# z+ O
  872. /* Returns:                                                                                                                                */
    , F% M, K2 O4 I# x3 z: t: k. j" q
  873. /*                Nothing                                                                                                                        */6 B2 G- u2 N7 k: K6 U
  874. /************************************************************************/
    4 h0 U$ {. T+ \
  875. void Sector_Erase(unsigned long Dst)
    5 P" B/ j% z* W  @0 B/ f
  876. {. [! W% _7 K  n; a4 O
  877. " M% B0 ~. t5 m4 d1 J& N0 ^
  878. ' l' G% F6 \3 {; g9 \- t7 y
  879.         CE_Low();                                        /* enable device */) v: W1 H; K5 G; p% N
  880.         Send_Byte(0x20);                        /* send Sector Erase command */8 k  C  U; J6 [$ J
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */1 G5 |% r3 ?7 ^# O; j/ {! C0 ]4 I
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));! k2 q( t* B" D) l
  883.         Send_Byte(Dst & 0xFF);8 g9 l) c# ?7 n- v1 C' Y! A
  884.         CE_High();                                        /* disable device */
    . K1 p5 T: I/ ?9 G6 c
  885. }       
    + z: m6 [$ _% V& `3 {5 q/ w4 c( p0 l

  886. 0 N6 l1 |# \% k1 G( ~
  887. /************************************************************************/% J7 y& l% s+ M  D( a  G
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */2 v' n# x$ N6 W7 H5 B  `" ]8 L, [
  889. /*                                                                                                                                                */
    8 g: m1 p0 F* B) D: t* A% }
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    1 R& d1 c: m+ E) A1 S; r' y8 k
  891. /*                                                                                                                                                */: k* ]* ?3 E5 i- a
  892. /* Input:                                                                                                                                */
    # d( r3 I1 S, V4 ]. t) k5 b
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    " b4 P7 r( x, e5 k, A& D! ?
  894. /*                                                                                                                                                */
    2 I" Z: R1 p2 l) x6 ]& t6 E
  895. /* Returns:                                                                                                                                */
    ( [* D: z4 ^3 P$ m8 z' k% g% @
  896. /*                Nothing                                                                                                                        */) ^/ K0 k) X. x! o5 m( W
  897. /************************************************************************/3 p; `! C' t8 g. N+ g
  898. void Block_Erase_32K(unsigned long Dst)
    . {: |% n4 q  U
  899. {1 u& ]* J5 J( V8 a& Z# M
  900.         CE_Low();                                        /* enable device */
    ' J. i% t4 b& `  z# u
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */2 q1 c5 k' B& s
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */( {2 T0 G& y0 D6 y) ~* k& z
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));, R6 K3 ^: [# o3 ~
  904.         Send_Byte(Dst & 0xFF);0 E4 ?. M! [  U! A: s! d: x
  905.         CE_High();                                        /* disable device */6 `  M) J6 [. N2 u+ D
  906. }1 B* r, Y' {, k) z4 y' O, x3 @

  907. : s# z4 k+ h8 M
  908. /************************************************************************/
    , k( V$ ~8 r; z9 o( V' U! y
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    " m8 R5 d% p) w/ a. y) P
  910. /*                                                                                                                                                */# M/ @8 |0 j& ]! `! A  M
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    # G' R4 l9 d) z& N8 u1 @: t
  912. /*                                                                                                                                                */
    + h3 B1 \' |* Z/ z) d/ o
  913. /* Input:                                                                                                                                *// h! u7 N$ D* K8 \
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ! [. G5 U$ }0 @" x
  915. /*                                                                                                                                                */, o: K+ M8 _7 ~8 J# h6 G; ?
  916. /* Returns:                                                                                                                                */1 ~5 N0 B: _+ f8 L  h8 e
  917. /*                Nothing                                                                                                                        */
    , q4 H: i" u0 \  g! ^
  918. /************************************************************************/
    " x; x# z0 Z4 G; @* ~5 N
  919. void Block_Erase_64K(unsigned long Dst)
    0 J0 r, j: P; K) I0 h
  920. {
    % x' b1 ?' }+ x, G% K" ?6 N
  921.         CE_Low();                                        /* enable device */
    * Q$ D- |) Z0 n9 T, Y( w; ]
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */6 |8 r3 h5 R% Q5 e/ k8 y% f
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    1 i8 f: t9 U4 o  v
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));5 R6 x; T0 `! }9 {. [
  925.         Send_Byte(Dst & 0xFF);
    & X9 p5 O" e* X
  926.         CE_High();                                        /* disable device */4 x  I: j, p/ Z, R  E
  927. }
    3 c% t. s9 }4 W0 R
  928. 5 g, P6 ]% t) _! \& j! V- W
  929. /************************************************************************/* N5 R7 |! ]: C, u# t8 F) A8 {/ u! B% H
  930. /* PROCEDURE: Wait_Busy                                                                                                        */8 X# b2 E( g7 E" f" W5 d" p
  931. /*                                                                                                                                                *// E) `8 t+ z1 C1 ?! K$ `
  932. /* This procedure waits until device is no longer busy (can be used by        */
    ( K  J3 }. M7 i1 l
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    * C7 ]. f" S, x0 x4 A/ U
  934. /*                                                                                                                                                */
    * u8 W' B6 k0 B3 r: ^
  935. /* Input:                                                                                                                                */. O5 K- c" R: A- W- x* E
  936. /*                None                                                                                                                        */
    9 b+ A3 X6 C( j. H
  937. /*                                                                                                                                                */
    / v% j3 Y' z9 }# m+ b
  938. /* Returns:                                                                                                                                */2 {8 x! V2 U* T- ~
  939. /*                Nothing                                                                                                                        */
    & Z. w/ h# N% r$ l
  940. /************************************************************************/
    9 D* n# M- S0 }7 q# F, q! F
  941. void Wait_Busy()* {6 d- C. s7 K6 o3 `
  942. {# `% W, t" X" L. z1 O) q
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */$ M, P: j4 _) o. @" U8 w6 `+ z
  944.                 Read_Status_Register();( y4 C2 \5 [3 @! u1 L. T
  945. }
    1 `& b4 @8 M0 h% b/ R$ [1 p( w8 V
  946. : A5 a- Q7 n2 g+ L7 M4 L
  947. /************************************************************************/
    5 M4 j+ L8 h5 L" M' y1 s
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */1 B' U$ N- k9 H1 i9 x
  949. /*                                                                                                                                                */
    , q- p' O8 U1 Q' ^0 v! I
  950. /* This procedure waits until device is no longer busy for AAI mode.        */, z" j! p" @0 _4 ?+ B$ i
  951. /*                                                                                                                                                */5 L" c- a& k$ H" _+ u0 U, r: x+ E0 H
  952. /* Input:                                                                                                                                */
    6 m4 W, r1 p7 u) e7 w2 u
  953. /*                None                                                                                                                        */+ {2 L2 w! L9 ]  l
  954. /*                                                                                                                                                */, @# G: o3 k; G4 x; B
  955. /* Returns:                                                                                                                                */
    & C, j9 T4 C7 b' P0 _+ P6 ]
  956. /*                Nothing                                                                                                                        */' V' S5 c& w" o2 ~% z* Q* P
  957. /************************************************************************/
    ; |. v5 A1 ]8 Q
  958. void Wait_Busy_AAI()  W% j; a- |5 o) s
  959. {# P& j0 u! k+ Z9 H* s
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy *// _3 v7 T& F) H( b
  961.                 Read_Status_Register();+ C3 e( G# u3 y( P' _+ ?
  962. }
    + O' b3 Z3 c# }8 W- J) n' O4 L
  963. ) ~9 |" b3 D0 s, r$ s* u  T
  964. /************************************************************************/
    ( J* T! l% r) G$ A1 j8 o1 U1 V
  965. /* PROCEDURE: WREN_Check                                                                                                */
    8 \1 J. O8 R: U* P0 q4 W
  966. /*                                                                                                                                                */! K' S& x3 `/ I2 V) _7 y+ K
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    - ^; K! `4 _8 k% E
  968. /*                                                                                                                                                */' T6 A; n0 N/ [5 A# {3 j  W/ P# N
  969. /* Input:                                                                                                                                */! r) }9 M( Z/ ?5 z6 Z
  970. /*                None                                                                                                                        */
    8 u# X3 {4 X3 ^, h7 {1 u% o: f. W
  971. /*                                                                                                                                                */
    . T* e8 q* g' Q' C- q8 o+ t- L
  972. /* Returns:                                                                                                                                */( w1 G2 h3 Q: s" S# h- K0 F
  973. /*                Nothing                                                                                                                        */
    & N! e( k4 j) f7 _
  974. /************************************************************************/
    : g5 E0 F! a) y0 Z
  975. void WREN_Check()
    9 j9 |. b/ j* o! A  {. R
  976. {% ]/ h' T4 O$ w8 n
  977.         unsigned char byte;* ]' i; q( X% V+ P9 W
  978.         byte = Read_Status_Register();        /* read the status register */
    " o' s1 I! i5 F5 I) ], O$ [0 u
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
      b6 G/ U8 r& C1 W7 w3 a# S0 w1 x
  980.         {
    3 _( }6 o+ {/ c! O
  981.                 while(1)
    + b( w4 X% A7 _/ }0 v
  982.                         /* add source code or statements for this file */
    0 L8 P+ f  W+ o3 d: S. a$ u) L
  983.                         /* to compile                                  */0 Q# }. b$ k: t  i
  984.                         /* i.e. option: insert a display to view error on LED? */5 W& }& {2 X4 E( o
  985.                  : o' v2 o5 N& k  [4 l
  986.         }' O) _2 ~- }8 U2 q# u  e# _
  987. }
    - q. g: q5 D# c* k

  988. 7 N' J/ `/ ]' ]. i+ C- J
  989. /************************************************************************/1 X1 p1 g7 i  S
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    8 R8 \$ L/ T) b
  991. /*                                                                                                                                                */
    - o' k$ T5 ^$ F6 l' N
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    1 A: H" o5 T3 H
  993. /*                                                                                                                                                */
    . z2 o: d2 t$ R; L
  994. /* Input:                                                                                                                                */! I( U" P( U. k; w: D
  995. /*                None                                                                                                                        */
    * R8 O) K6 ?9 t) J, |* x' Y
  996. /*                                                                                                                                                */
    ' R& D: h) i& p3 B
  997. /* Returns:                                                                                                                                */
    4 T* C- I) Q+ u( G# L9 T
  998. /*                Nothing                                                                                                                        */
      j- b' {# B3 \0 L
  999. /************************************************************************/  P7 u1 H% _( |8 a1 q$ F
  1000. void WREN_AAI_Check()) q4 o+ V6 Y) M. I, k0 R4 V2 x% n
  1001. {* T/ l, B: b5 C$ I+ C7 [
  1002.         unsigned char byte;% p' Z+ b4 H# F/ u3 d9 B, c# x6 J) \
  1003.         byte = Read_Status_Register();        /* read the status register */9 g" Z/ [- k- A3 t$ p( n( R
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */1 M; N* D6 G! ?; |! g; ?1 z
  1005.         {
    . F4 z- M; x+ z. N
  1006.                 while(1)                " M8 o& @# z  o1 P% G2 a2 e' ^8 g
  1007.                         /* add source code or statements for this file */) f) e( _8 P' V4 p
  1008.                         /* to compile                                  */
    3 n0 _1 L& a# C# @3 G* o; P
  1009.                         /* i.e. option: insert a display to view error on LED? */* R: _) l) k! i; v( f3 i+ D

  1010. ' o! `( @0 b+ N$ ^1 R; @
  1011.         }' [* p9 u- b$ v
  1012. }
    6 b% d  [, F# v3 n0 _$ k( X! L
  1013. & Z; k3 M+ `# N5 i. p4 `& D, }
  1014. /************************************************************************/
    ' b- I' X0 S% W7 h4 J7 C
  1015. /* PROCEDURE: Verify                                                                                                        */
    . x7 V/ K+ ]1 A/ G- O% u
  1016. /*                                                                                                                                                */
    8 ]1 n6 ]2 v; [9 I* R6 M2 Y3 ?
  1017. /* This procedure checks to see if the correct byte has be read.                */
    6 Y9 R: m# u/ Z9 ?% N/ |& l1 k
  1018. /*                                                                                                                                                */6 W/ }1 M, G' H2 l* S; l* D! A
  1019. /* Input:                                                                                                                                */
    % ?' p6 H- B- s0 }' w
  1020. /*                byte:                byte read                                                                                        */" H% w, V: o! I6 r4 H" Q% _. K2 ~- S
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    # }2 U$ H1 b0 e% n# G0 r
  1022. /*                                                                                                                                                */$ p3 ]- q/ [9 B0 H
  1023. /* Returns:                                                                                                                                */
    2 s' `: I, }5 S+ I& }+ P8 X
  1024. /*                Nothing                                                                                                                        */) y) t$ Z* m: A& F
  1025. /************************************************************************/  f! ~0 M& j5 \/ s
  1026. void Verify(unsigned char byte, unsigned char cor_byte)$ n  V5 e; h/ \, O
  1027. {1 c. ?. d& }# r0 b
  1028.         if (byte != cor_byte)
    - V$ g3 \0 U: B5 h; ?, z) L
  1029.         {! [. }! t4 t: I0 H
  1030.                 while(1)
    $ \; W' ]) I+ e' f
  1031.                         /* add source code or statement for this file */* K1 o- i, ^- L) t4 [& i1 f3 K  E4 ^* G) A
  1032.                         /* to compile                                  */
    7 ^, f8 T; I( S
  1033.                         /* i.e. option: insert a display to view error on LED? */8 W8 o& Z% f: Z6 q5 P: k- U5 O
  1034.                 2 h# T, T; \; \9 N. h  p0 y
  1035.         }  g+ ~6 [# Y; b
  1036. }
    ! @9 E9 b# `) Q5 v
  1037. 8 [# m$ @+ A; r& b  I
  1038. - b1 u) E9 U2 V/ B" ]" c+ g
  1039. int main()8 u7 x# R) p" U7 y/ T
  1040. {
    ' B( @4 A# e) _, G& h& H; y1 t9 r

  1041. " h; p/ i# z3 I) ?3 D. u" J
  1042. return 0;
    ! f8 P5 _9 G" x
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
* f8 X7 \9 l' n( Q   main()
. p5 h& C' i7 G   里面怎么是空的呢?
4 X8 l9 J. {6 R& b8 d) [   发一份给我吧0 ^( n4 S' L; y& U: N; L, h  g* ~
mail:luyijun2005@hotmail.com, v! K/ b) z7 C- x4 i% u
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
* G: s5 l3 c9 [. q) J* p  T, ~& w7 Z% x2 J
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
" I- v0 {! A% }% ?* sEC的代码在哪跑,你看DS的说明,每个EC都不同的。
- n, t. o4 d# F6 d' ]0 F* [9 cOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?% S+ T( _) N4 x- x* T1 B# i
上面几个问题是你没看任何东西而白问。
+ f- H4 w$ d* e6 P" o7 y
1 N. R0 z! a6 A( H; F5 ]) [5 r至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

- E6 L2 j/ n5 }. G- g  j7 K1 f关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
, i( m4 ?. i- I4 d1 [5 e- F* _5 v2 W' ?- e
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
$ J/ S& h$ f% f& P' _6 ]% w/ w; i/ W3 n: J$ E; y8 ?3 i( o
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样5 n1 G2 ?" t( d" b% R" A8 S
似乎要把SPI能support 到最大,这EC chip应该有好卖点* s5 K/ k+ x" D, _3 [
BIOS功能要不要强大,也就决定了SPI Flach的大小
$ i) U+ Y* E% F( d4 ?" H( L我是这么想的~让OEM去决定要挂多大!2 j1 t- b8 |9 d* H6 F; {/ H
如果我司有BIOS工程师就好了~哈
0 L% ^1 n, S6 @1 ?, C5 x  N- {WPCE775应该算很新的东西,来看它支持到多大?
# ~( `) d( r3 \! u4 ?+ h7 y, k1 h( U8 [0 I# o
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
1 ^4 c8 H3 ]  F其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.0 M: L5 N) H; {2 K& @

5 Y, j) l2 O4 v这份driver收下~希望以后有用到
. `, c0 o4 n0 _/ l7 n/ ~% k+ l2 b谢谢bini大大7 M/ z: ]4 |  Y. @

2 |* o0 U; j4 n很新很新的新手,如有错误请指正 (准备看第二家的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()6 @7 x) \' a( ]6 g
{
" v" r& O# y1 y+ w( M7 z        unsigned char temp = 0;
& w: u4 j: t" c0 X        CE_Low();! h* |* M0 J+ W% ]+ }/ Q
    while (temp == 0x00)        /* waste time until not busy */
; W6 W# \5 E; N1 z                temp = SO;2 n7 H0 x4 t! ]7 H) X$ t
        CE_High();
$ v& ~+ U1 t& `3 Z1 D}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)/ C8 A& j/ L  R# O$ h! x
{0 ?. f- H+ o( X& b1 h" `  w1 t' e
        % `9 k' R4 x% g3 |  h0 u
        unsigned char i = 0;, z1 O4 t2 T- v" A1 A
        for (i = 0; i < 8; i++)- w4 R9 X) q4 I
        {' r' |% s1 S% k- j
                $ ~- y% ?$ t8 m/ z* ^
                if ((out & 0x80) == 0x80)        /* check if MSB is high */; y5 ^( s4 q0 _: h) C  d; `
                        SI = 1;
" {+ ~* |, v. ~( M                else
" t- X3 [+ r4 t* l; y6 V                        SI = 0;                                /* if not, set to low */) l1 O7 g$ l$ p2 @8 w
问              SCK = 1;                                /* toggle clock high */
0 O/ [" \; a7 q+ T$ p   题            out = (out << 1);                /* shift 1 place for next bit */
3 u" e+ M, h0 C                SCK = 0;                                /* toggle clock low */4 K$ m: v6 s. l3 o% S/ m
        }
5 p. Y1 Q2 e1 o; ~}
+ o1 Q& [( ^! j7 J! d' M 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-19 06:28 , Processed in 0.029564 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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