找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54756|回复: 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 Driver9 P! r4 e& l  L" {) y# m" g
  2. ( l% b0 k8 g; H8 r
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    1 Y2 w8 O5 W" P

  4.   i! s" C5 B4 U4 l* t
  5. November 4th, 2005, Rev. 1.0
    ( G5 k  q" f& h- ~+ z1 k
  6. 2 c; S# P3 l0 t! \( y0 [
  7. ABOUT THE SOFTWARE1 A; h9 W) }% K) D
  8. This application note provides software driver examples for SST25VF080B,
    # v1 I6 ?+ K) H$ K- ^
  9. Serial Flash. Extensive comments are included in each routine to describe
    " G8 f  d- Y+ c) W: m6 b: o
  10. the function of each routine.  The interface coding uses polling method * V7 a' h. |+ T' w, n& j3 N' _2 R
  11. rather than the SPI protocol to interface with these serial devices.  The9 v. _! V7 i( p
  12. functions are differentiated below in terms of the communication protocols
    . L& F! L8 U& \8 B2 w* ]
  13. (uses Mode 0) and specific device operation instructions. This code has been
    6 \! @- |" _5 ]6 @2 V. x1 o* [
  14. designed to compile using the Keil compiler.5 w  ?1 ?$ h. `3 r' ]# H
  15.   r! r9 P+ p% X; k6 A
  16. + A( c4 v+ G7 h. ?
  17. ABOUT THE SST25VF080B
    / l& ]/ v9 T, x7 D9 ]5 ?) D  L7 b/ N
  18. ! J+ w% G( E+ N& E' B
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    4 a; ~: D% N" [. d: y5 y
  20. conjunction with this application note for a complete understanding ; e) R/ l& q, J1 _' _, Y
  21. of the device.- Y5 Q$ p$ n- x  b) s, M
  22. # \% U% A3 ?% _$ z6 n

  23. 1 w, b! k6 x3 w' @! h  K
  24. Device Communication Protocol(pinout related) functions:
    % K2 z& T0 o) V6 c

  25. + n" h+ y( y' C, j
  26. Functions                                    Function
    # V; |, B; L0 o/ `! k
  27. ------------------------------------------------------------------
    - u/ d( }7 {, g$ c" l
  28. init                                        Initializes clock to set up mode 0.4 u) u4 G7 T! j3 j5 v$ x) A
  29. Send_Byte                                Sends one byte using SI pin to send and
    ' j- O, }8 V  n9 W5 d& \+ [  A& s
  30.                                                 shift out 1-bit per clock rising edge. f& ^' @. ]- V1 R! ~
  31. Get_Byte                                Receives one byte using SO pin to receive and shift " ?1 I8 V( W; ]) x; ]
  32.                                                 in 1-bit per clock falling edge& L0 F4 q& k* m: \% e; K* J+ z
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    5 f7 G  C+ w* G% D( k. R
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high3 c9 V9 H  t" t6 R
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    # Z- k* Z1 d% t5 z: o4 E& s9 e
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    2 a& H0 l. Z. x( V0 z' F/ r) ~
  37. Unhold                                        Unholds the serial flash1 h. O8 \. L) J: @1 U% a6 p" V
  38. WP_Low                                        Clears WP pin to make serial flash write protected" ~0 a/ W0 Z- G: k
  39. UnWP                                        Disables write protection pin
    9 ^: \& F0 @: i1 y, m

  40. + s, g' ]" V$ l
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    & F5 j/ P" C" w' g6 I! h
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    , f" f) M5 H% o, C: a
  43. software which should reflect your hardware interfaced.          
    2 q/ V- x5 G# S' H6 t( X
  44. 7 A4 R9 K/ l, z8 W7 g: W% h7 Q
  45. " d7 O" S5 _, w2 n7 M4 u8 z& ?. a
  46. Device Operation Instruction functions:
    ( P: s+ W( _$ x) ^4 n1 H
  47. , L% u  Z: `, E% H% B+ p. _8 \, X
  48. Functions                                    Function! G7 W( D1 _4 R  P6 s! H- I
  49. ------------------------------------------------------------------
    , c4 i9 @; i7 o/ Y4 r( D) S; n0 m
  50. Read_Status_Register        Reads the status register of the serial flash
    ; x  M5 c3 o  V5 b0 P! ~
  51. EWSR                                        Enables the Write Status Register
    9 {: g, |, c1 s$ `9 z! z) m
  52. WRSR                                        Performs a write to the status register
    0 ^7 n8 ?9 D5 a( v5 @2 p
  53. WREN                                        Write enables the serial flash
    ( D6 p$ d8 ]3 H% r% X# k. H& [
  54. WRDI                                        Write disables the serial flash
    * |% \& o2 L2 Z6 k
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    0 K$ w) i5 ~4 D2 `' C! ?( e
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    4 [6 a$ ^; N1 N4 ?( y! K
  57. Read_ID                                        Reads the manufacturer ID and device ID" F# Z# ?$ K- p9 L  y  M
  58. Jedec_ID_Read                        Reads the Jedec ID% m) V1 M1 ]7 ^
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency), ~5 L$ ]3 [& p) F
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    ; e; m, N! K0 {* s/ B: z9 u
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)+ i3 {3 t2 Z' o' M% ]
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    . t- M* n* F# h( F2 X
  63. Byte_Program                        Program one byte to the serial flash
    . N+ b( K9 Z% M; B  h$ D
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    * ?  D8 l+ p; u6 F2 ~2 P- c0 n
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    - ]! e  E! X( N* U6 X8 K; \5 \' h
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    4 d2 R, s; ~* D+ t3 Z! q, h4 _
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    ! d1 r% i& `: a, I
  68. Chip_Erase                                Erases entire serial flash
    7 S5 s( K# z' V8 ?: Z- i! u( o
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    ; E4 v$ y5 k5 ~; X% z) w
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    - t  i, `$ J7 ~0 N
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash9 P: V, ~& G( Q! Y% B% {; Y2 Q
  72. Wait_Busy                                Polls status register until busy bit is low
    + `: F8 n% C; r. ~( @
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    ! l4 p; Z5 ?9 l) N6 t  e
  74. WREN_Check                                Checks to see if WEL is set& H# e* ^' v0 T
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set/ U: B5 x2 _6 `6 ~" J* \

  76. & D4 K1 X7 S( K( h: z

  77.   p1 C/ E0 ]: J& a8 c8 v. s/ N9 Q

  78. 0 v* |2 j% Y4 d1 i
  79.                                                                      
    0 A  _) W8 V: ^' v
  80. "C" LANGUAGE DRIVERS
    $ I# e& `$ d* g+ R

  81. ' ]( A4 A% `! C: P. Z
  82. /********************************************************************/& O! q8 ^8 H6 f$ v0 E
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    ' [3 j: J5 E# R; o" |% T0 |: I1 P% O* x
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */4 E) N; t4 l( H$ y5 F  Q
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  *// g4 j3 B+ E' Z
  86. /*                                                                  */% I+ ]# V' A8 }& ^0 X9 p2 ?- d7 L
  87. /* Revision 1.0, November 4th, 2005                                                                          */   : t1 E7 V' g) t+ j7 G/ _
  88. /*                                                                  */
    7 z  N$ b0 O3 S' G
  89. /*                                                                                                                                        */
    " S  K0 l$ k* s7 Q3 Y& l  s
  90. /********************************************************************/" X  I; ]5 d% K: k8 S4 o
  91. " s: N% ~, C1 A2 H
  92. #include <stdio.h>3 o' {" z! x  i* ]/ L
  93. #include <stdlib.h>) B  Q) G  O2 s9 c8 ]" B

  94. + {$ I( y$ Z0 w/ u9 Q0 L9 T* b. u
  95. /* Function Prototypes */
    ' a0 w: s% v2 S/ y1 K# I" z3 U# \; ~" ]

  96. & ~" i( A( X4 F: Y6 ^* K
  97. void init();+ U7 k9 l. i( \7 S8 l% g! N7 |
  98. void Send_Byte(unsigned char out);
    ) J9 K+ i( [. J# P" R
  99. unsigned char Get_Byte();3 Z5 q. T* I5 a. ?7 n) D5 {# ~
  100. void Poll_SO();
    7 p3 [- }, S) W+ y5 O$ v$ C
  101. void CE_High();2 L! b+ t/ L! a. m% L$ @5 D, W
  102. void CE_Low();
      V' F* s2 P4 o9 e9 o& r
  103. void Hold_Low();
    + @: O6 k2 K* e8 b/ F+ V
  104. void Unhold();% T' {6 B0 R7 Q- C
  105. void WP_Low();1 T" r% ^" g  a3 J- s/ ]/ O
  106. void UnWP();
    + ?: D9 m: J, Z" f
  107. unsigned char Read_Status_Register();
    ( X' }2 R  O' \" @, [
  108. void EWSR();
    8 u+ ?$ c, G' D& `% I
  109. void WRSR(byte);; `* Q6 n' b. o5 j1 D* u
  110. void WREN();
    , u* u* v0 C1 V/ j
  111. void WRDI();
    ; V7 t  t7 q* A( b) Q4 o
  112. void EBSY();
    . v6 \0 m% {# M
  113. void DBSY();
    ) p, w$ e! h% b1 o) I
  114. unsigned char Read_ID(ID_addr);
    : h' E& k; |: V7 I; [, [2 s
  115. unsigned long Jedec_ID_Read();
    % j$ P% x( x* m* H# O6 R3 ~
  116. unsigned char Read(unsigned long Dst);3 I$ N& Q. g9 c$ G) F
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);4 ~6 Q# @) z( J  u
  118. unsigned char HighSpeed_Read(unsigned long Dst); * o5 i  U2 |# O
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    6 f2 l2 \. p! a  n% \
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    8 U3 ]& J4 d3 G" x5 x* P
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    & w8 e9 }2 i7 q1 E: J
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);2 I/ S5 }& U* ~6 h- v) J2 z
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);3 P& |! r6 W: M6 c4 g: `
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);: X; K! h; q0 z' |2 D5 p$ v4 ?6 ]: j1 ?
  125. void Chip_Erase();# O7 n, s& X  @8 g  n
  126. void Sector_Erase(unsigned long Dst);
    / h' n* {5 T5 ]* o( ~
  127. void Block_Erase_32K(unsigned long Dst);
    . I4 R" H' y) |2 t, o, i% ~5 A
  128. void Block_Erase_64K(unsigned long Dst);( j$ \; e* Y$ l0 _9 n. W
  129. void Wait_Busy();
    7 R- ?& v- n9 D+ o8 r8 D
  130. void Wait_Busy_AAI();& t; s- d! ]8 @8 X* F. v
  131. void WREN_Check();
    " B) q+ L' E3 B
  132. void WREN_AAI_Check();
    , {8 }& U8 y# G. N" N8 Z' C4 V

  133. $ ~/ M6 o/ D& H, c+ e) f1 o7 b
  134. void Verify(unsigned char byte, unsigned char cor_byte);" v* Q9 n) `- ~: l7 ^  F
  135. 1 G" H9 V, V% l- S7 w
  136. unsigned char idata upper_128[128];                /* global array to store read data */  [) n% S  _6 h. |0 H
  137.                                                                                 /* to upper RAM area from 80H - FFH */9 Y0 {, p" x2 ~; E

  138.   d4 A" a! x& J% ^. G* E
  139. /************************************************************************/
    . C* h8 N" A4 o2 C1 ]
  140. /* PROCEDURE: init                                                                                                                */
    ! A5 |8 K+ R+ c# q0 W
  141. /*                                                                                                                                                */
      H1 g8 l: I2 @+ n
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    - [  g( C9 G1 T2 {( o3 {
  143. /* setting up mode 0.                                                                                                        */
    - m% t  V" o, B% v
  144. /*                                                                                                                                                */: _/ B0 L/ i2 `
  145. /* Input:                                                                                                                                *// Q% M/ X7 F' B: `' {5 _
  146. /*                None                                                                                                                        */1 q! F/ C) d6 H  c: w
  147. /*                                                                                                                                                */: y# w6 V1 F. a! t: q
  148. /* Output:                                                                                                                                */; A, n) v: Y' J3 N) \# M
  149. /*                SCK                                                                                                                                *// e2 a8 G  n. W0 @
  150. /************************************************************************/
    " Y5 Z& U. U2 K: l
  151. void init(); m. o  b: P. w9 y
  152. {
    1 W! Z1 j' P  F3 i- t) c, g! b" x
  153.         SCK = 0;        /* set clock to low initial state */
    3 {3 R. E5 g" l- z- V; r# i
  154. }
    ; t4 n9 j+ Y- M4 h& J

  155. 5 F1 N5 h- C8 m- x, p& y
  156. /************************************************************************/
    4 S  |  K7 X6 d: U  O
  157. /* PROCEDURE: Send_Byte                                                                                                        */% s0 K7 y: L6 O- y3 E" x- }( s4 Q5 y
  158. /*                                                                                                                                                */0 y9 W4 d& @: W& K# D
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    6 v/ c0 A9 V" m% \2 c
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    * ^: g) a$ v8 O/ l
  161. /*                                                                                                                                                */* m0 O) G; T, A
  162. /* Input:                                                                                                                                */8 E; u2 n; j; l- v: R+ v1 w
  163. /*                out                                                                                                                                */
    * I% @: b, q& Y: ?3 q
  164. /*                                                                                                                                                */
    $ N& R% Z$ ]/ f6 U% }4 X
  165. /* Output:                                                                                                                                */+ M, Y# O4 M* q  a; a( O! z! q+ M5 a
  166. /*                SI                                                                                                                                */8 }, h' v6 Z- u- y- j/ _
  167. /************************************************************************/
    1 S. }9 H/ b9 ~
  168. void Send_Byte(unsigned char out)! h) n; l/ j; X) k; a- a: g3 e
  169. {
    $ e# F0 N/ B* ^; {3 c* y% p
  170.         $ `) C! X5 V/ j9 ^
  171.         unsigned char i = 0;+ @6 T3 o) J4 B9 ?) u5 C$ _
  172.         for (i = 0; i < 8; i++)
    , Q( e( m' [! e' l
  173.         {
    ( E! @* x8 I" X& t6 a2 i
  174.                 + b8 g* b" i  f* ^8 m& M
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */. ?, u3 r/ o" W" B! b4 V
  176.                         SI = 1;4 b1 G6 W1 w/ o! N8 T
  177.                 else
    ( R% n3 ^5 m: h) B* ~7 s
  178.                         SI = 0;                                /* if not, set to low */
    8 i. l+ a% G' u/ e, g
  179.                 SCK = 1;                                /* toggle clock high */
    1 D+ c* n" N6 `5 h$ p# r6 a6 @
  180.                 out = (out << 1);                /* shift 1 place for next bit */, K0 r, p( W- u+ O! }; v( Y
  181.                 SCK = 0;                                /* toggle clock low */. [2 {' v9 Q$ K& r( o' @+ N
  182.         }
    8 b) i5 H+ ^4 c* l  a6 J- }* c
  183. }% J/ ^9 E, j1 N5 W
  184.   J9 K, X6 Z' d  Y& I7 t7 {# U  C
  185. /************************************************************************/
    ! ~& E' I; }$ l1 t7 F' y
  186. /* PROCEDURE: Get_Byte                                                                                                        */$ c; G' j9 n/ o: I1 L0 b( f, n' `
  187. /*                                                                                                                                                */
    / ^0 E2 e! `2 a% H/ h& h5 r
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */! Y6 a! v' C- a+ [3 d
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    4 }8 Y' g% Z( V4 S% f: G
  190. /*                                                                                                                                                */5 n% u7 E$ s8 x. T: a5 X$ l
  191. /* Input:                                                                                                                                */
    * r  R3 v* {- u
  192. /*                SO                                                                                                                                */
    4 }/ N. T) ]" q0 k- M
  193. /*                                                                                                                                                */
    ( l* O# @0 }  Z
  194. /* Output:                                                                                                                                */
    + ]1 a: K# c; G% I, \% [1 h
  195. /*                None                                                                                                                        */: H- D2 ]1 L* E- Q1 e' }# ^  Z5 T
  196. /************************************************************************/
    ) e) n9 q. ?0 h. o
  197. unsigned char Get_Byte()
    # Z+ }# I7 y3 D% w
  198. {
    2 u2 P7 [0 h2 @, Y" h9 M
  199.         unsigned char i = 0, in = 0, temp = 0;$ O7 X7 p+ Q8 s5 y# O
  200.         for (i = 0; i < 8; i++)6 [% Z, O$ r3 e& F" \$ B
  201.         {$ r# i! d4 }: O( C! W
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    ; ~0 @8 _  I0 ?4 k2 M/ L  s
  203.                 temp = SO;                        /* save input */; K$ Y6 U) T8 a# t; Q* a4 O% D) w
  204.                 SCK = 1;                        /* toggle clock high */
    & j& x  C0 e  O' ~' D
  205.                 if (temp == 1)                        /* check to see if bit is high */# J  m( o1 z; T1 R5 |* y# |
  206.                         in = in | 0x01;                /* if high, make bit high */# E, w# V! S: B9 W

  207.   o8 {0 Q( t& t5 W: c# d
  208.                 SCK = 0;                        /* toggle clock low */
    ) P0 k* @' I0 q  w5 M/ l
  209. 5 [1 x& `( K$ @0 s# ~. i1 Y
  210.         }6 b; [4 p6 t4 T9 N/ @; i
  211.         return in;
    " J1 N+ P( A7 `0 y% s
  212. }
    / a5 H0 N; i) B2 y# u0 d( ~

  213. 5 J0 y% ?: v: y6 e
  214. /************************************************************************/
    / l. a  ]; m4 u! E! j
  215. /* PROCEDURE: Poll_SO                                                                                                        */3 c; Q6 L, A" l0 V) d: S
  216. /*                                                                                                                                                */. e: c8 p+ ~  V( x% z" H
  217. /* This procedure polls for the SO line during AAI programming                  */$ K$ E9 G4 X" V0 ~/ {
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/3 h! X. Z0 Y7 b5 S  h# F) X! J
  219. /* is completed                                                                                                                        */2 V; P. `* |4 \: s  I# y) |9 L$ t
  220. /*                                                                                                                                                */
    - e% W2 h1 p# v4 @9 G7 q( I
  221. /* Input:                                                                                                                                */( e+ r% k5 U: E; s, f# ~
  222. /*                SO                                                                                                                                */" m9 b! ]7 k$ Z+ X  s, i
  223. /*                                                                                                                                                */- T- |$ l4 M# \6 j" L& i4 d
  224. /* Output:                                                                                                                                */
    8 |0 y" [* Q8 z! k% z
  225. /*                None                                                                                                                        */
    5 i. \: P4 K8 j; d
  226. /************************************************************************/
    " w$ s4 A3 @2 _2 G, Z
  227. void Poll_SO()
    ; {4 H2 j! f* N% g, z& ^
  228. {" F( l$ C, N3 e4 q4 R" @% x
  229.         unsigned char temp = 0;  s, e6 `, u9 Y- h8 C
  230.         CE_Low();& n1 d3 o1 X2 I* \: S
  231.     while (temp == 0x00)        /* waste time until not busy */
    0 d: ^1 I! {3 E
  232.                 temp = SO;
    1 x. T; a6 O7 g" V' a7 [
  233.         CE_High();) I6 C5 Z& G+ d) H, ?
  234. }
    6 _; A0 t) P) F: x4 Z6 j( C- t+ R
  235. 4 y' n% s- z" R2 C* Q$ u
  236. /************************************************************************/
    2 H) \- T+ a( |# B
  237. /* PROCEDURE: CE_High                                                                                                        */5 J2 l, {# W3 f( [
  238. /*                                                                                                                                                */" t; J& \; v  ]& \# K% |
  239. /* This procedure set CE = High.                                                                                */: r4 o, d: y+ i: ?1 ^' \! ?
  240. /*                                                                                                                                                */
    * m- i6 C8 p, p9 d. t$ I
  241. /* Input:                                                                                                                                */
    8 [  H, D3 C7 p' g
  242. /*                None                                                                                                                        */
    % ]; h, w. G* O; Q+ _" t& |
  243. /*                                                                                                                                                */
    2 k' G: \" R$ o, U) n' g* P4 B
  244. /* Output:                                                                                                                                */: i' g8 x0 ~3 i. ]4 W
  245. /*                CE                                                                                                                                */2 _, x4 ~1 d0 H# |; }, @
  246. /*                                                                                                                                                */$ a: x1 f# x& G* W% e+ R
  247. /************************************************************************/2 z/ J1 b1 l' m3 K. @) w
  248. void CE_High() / I! t. Y7 r' R+ J6 \1 u2 y
  249. {
    1 e) {# J/ f+ L5 H, P
  250.         CE = 1;                                /* set CE high */% f9 f/ M& x* C/ A
  251. }
    7 ~& w3 z' M3 [$ n8 @

  252. . y; A2 d/ `1 q, d& N; |. H
  253. /************************************************************************/+ `% w0 C" z1 j
  254. /* PROCEDURE: CE_Low                                                                                                        */" g9 g& e9 u9 F# S9 `- q' L' M
  255. /*                                                                                                                                                */
    3 P" Q6 t4 G" h! F! X2 W" W# w
  256. /* This procedure drives the CE of the device to low.                                          */
    0 J$ @! r% v6 M7 U
  257. /*                                                                                                                                                */. |% a& t4 k0 }: I& d
  258. /* Input:                                                                                                                                */7 ~9 ^. u$ T5 A9 y0 v0 f
  259. /*                None                                                                                                                        */( k3 l0 z, s$ g- H
  260. /*                                                                                                                                                */
    " l3 \" k8 A7 ~8 o2 l
  261. /* Output:                                                                                                                                */$ x- a$ g7 |) |
  262. /*                CE                                                                                                                                */& A$ ~: h9 {' k& q3 |% b* ]) |3 H
  263. /*                                                                                                                                                */6 t3 |; }" P. E7 Q
  264. /************************************************************************/
    0 _# i8 }5 t& J& W2 s# R5 k
  265. void CE_Low() / V, N* ]& `. i
  266. {       
    , ]: c- R' ^3 F1 v1 X2 z
  267.         CE = 0;                                /* clear CE low */
    , b8 W$ r& p" V  h( u
  268. }
    9 o! K% o) _; u8 i
  269. / S/ v& y6 |+ |
  270. /************************************************************************/
    9 Z3 ^+ `# R3 o- C( k+ g3 f
  271. /* PROCEDURE: Hold()                                                                                                        */; g: A3 u3 D% G* M7 |4 x2 K
  272. /*                                                                                                                                                */
    # v! s( |1 I/ }, I
  273. /* This procedure clears the Hold pin to low.                                                        */
    1 H- M- r+ q1 ^% ^3 X. }: t
  274. /*                                                                                                                                                */
    7 x" z4 S# p# u" d2 r6 d
  275. /* Input:                                                                                                                                */
    : c' r1 Y8 }' v; T: W& S
  276. /*                None                                                                                                                        */. M# O/ Q6 O2 o
  277. /*                                                                                                                                                */
    1 y  T% x, E4 X) e( ~1 @$ _
  278. /* Output:                                                                                                                                */8 G  \) |9 c' h6 C& t) `9 E
  279. /*                Hold                                                                                                                        */
    2 T: {8 O6 W' z% B, g- b% ]
  280. /************************************************************************/5 h! y: Y. m0 }* a( }8 ^
  281. void Hold_Low()- V# g$ u/ d  u- Q5 O2 ?/ b
  282. {
    ' t2 {, B4 E! M% ~2 r
  283.         Hold = 0;                        /* clear Hold pin */5 k! b5 r7 U/ k, R
  284. }2 {4 n2 |& l6 I

  285. - F( l$ e" e" I& g
  286. /************************************************************************/
      b6 {! V& [. \
  287. /* PROCEDURE: Unhold()                                                                                                        */
    ( `0 K, g5 X1 s6 u! c4 v2 @( W" u
  288. /*                                                                                                                                                */, M( x# X( k3 x2 l& Y; h
  289. /* This procedure sets the Hold pin to high.                                                        */4 _# R5 b9 q& U" }$ p( }* \8 q2 [: t
  290. /*                                                                                                                                                */
    9 R* z0 Q3 i% Y) s  Z) W0 T
  291. /* Input:                                                                                                                                */
    1 x& |# v' R' W
  292. /*                None                                                                                                                        */+ ?: l0 I& k* Z
  293. /*                                                                                                                                                */: r- a8 M, D' G4 e" B  O+ w
  294. /* Output:                                                                                                                                */6 \$ J5 H5 i' q
  295. /*                Hold                                                                                                                        */$ a+ ?, S, N2 q
  296. /************************************************************************/& c  a" t" e4 f
  297. void Unhold()
    ) c7 u3 t( l# {- c; x- B) O3 [
  298. {
    ) A# [' J2 _3 n) A# e: Y; o
  299.         Hold = 1;                        /* set Hold pin */! |# f2 Z) Y7 Y5 j6 o- n
  300. }3 F  }# j) |7 I- e; B* M
  301. ( N; ^" W% _3 @/ r
  302. /************************************************************************/# E3 H8 ]6 ^6 c( ^, r( F
  303. /* PROCEDURE: WP()                                                                                                                */# _; ~6 e. }! W( Q' r, e" P
  304. /*                                                                                                                                                */
    2 F/ Q; M$ M" E4 }, f! p! T
  305. /* This procedure clears the WP pin to low.                                                                */
    / r# Y) [4 ^8 Y& s( w$ f3 T
  306. /*                                                                                                                                                */1 a' @  L, a1 v* I. |" }8 e
  307. /* Input:                                                                                                                                */2 k5 A% c+ N4 I+ `
  308. /*                None                                                                                                                        */
    ) ~( w* _4 z* \9 X' }7 l& H
  309. /*                                                                                                                                                */
    ; f/ T# M3 ^$ D0 B
  310. /* Output:                                                                                                                                */: u5 \+ i, w* W/ v
  311. /*                WP                                                                                                                                */1 G; w4 r7 ~1 b# Q% d# F( S
  312. /************************************************************************/! E: b: Q2 d* W8 \2 ^' L  r6 `
  313. void WP_Low()1 D8 R! n7 T1 P5 y* y% \
  314. {
    + k% `9 b. Q: ?" `8 g
  315.         WP = 0;                                /* clear WP pin */' ]8 Z; }2 M% I9 A" L2 K+ y
  316. }
    4 H/ Y# O& }4 e. {
  317. 4 J3 |/ b; [; V* E7 \& u5 m# B4 d
  318. /************************************************************************/
    ; s3 q  v. \% K: M  k  c
  319. /* PROCEDURE: UnWP()                                                                                                        */3 `) c+ {5 ?- u+ i2 X
  320. /*                                                                                                                                                */( g' V8 g' p6 f3 H, N; R
  321. /* This procedure sets the WP pin to high.                                                                */
    6 c$ G+ T/ C6 b7 X* i# ^( y8 X& s  k
  322. /*                                                                                                                                                */
    , G/ Y9 Z6 U; ]0 }+ J' |8 ~+ a& s+ i
  323. /* Input:                                                                                                                                */
    3 \5 ^, t; R1 O- f/ ~' H) F# j6 S& X
  324. /*                None                                                                                                                        */
    ! x! |' I) X/ Z
  325. /*                                                                                                                                                */+ e( c& B5 X$ \' o# n2 Y# f  F
  326. /* Output:                                                                                                                                */
    3 v- Q" Y  i# r8 ^! C! U! S
  327. /*                WP                                                                                                                                */
    2 w4 c' [4 Z7 K' N
  328. /************************************************************************/
    % T4 f( s( F" O0 K
  329. void UnWP()! z3 I2 X$ g3 J) m+ ^
  330. {
    + ^" l4 l, y6 q$ ?5 Z
  331.         WP = 1;                                /* set WP pin */
    * O; @7 [% K7 e7 e* a
  332. }: s& l5 ^2 ~) x' B2 a9 Z
  333. ( n, }' [1 J$ X. c- ]5 I
  334. /************************************************************************/
    - ?; m, P& f# u# I' C2 f
  335. /* PROCEDURE: Read_Status_Register                                                                                */# T/ y6 W( l' R
  336. /*                                                                                                                                                */2 Y- t( D4 F! r) l" P# f
  337. /* This procedure read the status register and returns the byte.                */" F, W2 K" S, o: d' A, [: K3 e  m
  338. /*                                                                                                                                                */
    , [$ u. G4 `) ^: A3 c
  339. /* Input:                                                                                                                                */$ W; Y  o# C/ I  Y1 S" {3 d! W* ?
  340. /*                None                                                                                                                        */7 K5 k/ N0 ?; Y4 A
  341. /*                                                                                                                                                */
    9 E3 v/ @/ ^6 m9 j( h) {8 q& V
  342. /* Returns:                                                                                                                                */
      I; k. W6 K# D* A0 }- }
  343. /*                byte                                                                                                                        */1 l4 n/ L1 C2 b$ v9 x+ m; M4 F* f  l, [
  344. /************************************************************************/
    ) G8 i& d$ G3 c3 u$ f
  345. unsigned char Read_Status_Register()
    ! q% i8 l$ f6 O
  346. {1 _6 v3 q5 i6 `3 Y7 d! r# W" |* C! \
  347.         unsigned char byte = 0;
    4 O9 i+ G- U2 m3 ?: B5 g4 R% B/ D
  348.         CE_Low();                                /* enable device */$ o7 p% ^& T3 v! p7 O# a
  349.         Send_Byte(0x05);                /* send RDSR command */: e0 ?( _7 N% t6 l& p+ \7 S/ W/ C
  350.         byte = Get_Byte();                /* receive byte */0 \* X0 q* h+ O( V, y# p. D0 O
  351.         CE_High();                                /* disable device */
    ; l+ _; f2 Z- @4 b, O
  352.         return byte;
    9 t$ ]. e8 o/ w) g2 G" ^
  353. }
    ' J; x3 H. ~5 Q  H! C" x, K

  354. % [! d  P6 d0 q4 N
  355. /************************************************************************/' d5 h* G8 p% G- Y- O4 _
  356. /* PROCEDURE: EWSR                                                                                                                */
    3 L3 r) Y2 S( G, K  f' ^* G) N. U
  357. /*                                                                                                                                                */
    6 n7 e$ H3 J4 I8 E
  358. /* This procedure Enables Write Status Register.                                                  */
    . w4 |: k5 ^8 r& x
  359. /*                                                                                                                                                */) A4 p+ V. q; y$ c" t" d, c5 ]
  360. /* Input:                                                                                                                                */
    $ v& S6 h" l  j" q+ l# z  D
  361. /*                None                                                                                                                        */) t  \+ ?3 f1 I$ \! T
  362. /*                                                                                                                                                */
    - ?, a, @: w8 D2 ^, O
  363. /* Returns:                                                                                                                                */
    5 O7 a% T3 m( `; o4 ?, {
  364. /*                Nothing                                                                                                                        */
    9 N& u: f9 T6 s" v, Z$ ]
  365. /************************************************************************/
    2 @8 L" l) a; w9 {- ]5 p
  366. void EWSR()
    " _, G' c0 h* k- |! K/ T% |
  367. {/ r% d5 E, I5 K  S4 V  `0 u3 I- O
  368.         CE_Low();                                /* enable device */
    . a6 S/ o; k  ], P0 o4 j
  369.         Send_Byte(0x50);                /* enable writing to the status register */3 }3 T: F8 V8 A0 o! H9 i( s, K. k5 p
  370.         CE_High();                                /* disable device */- Q- P0 U: F3 }% K
  371. }8 O/ W4 E3 f+ U2 y9 K6 i
  372. + i- u; Q/ n+ z
  373. /************************************************************************/
    . D# @. u- F- n9 |% B- E3 B+ w$ j- j! r* _
  374. /* PROCEDURE: WRSR                                                                                                                */
    " T. w  P" w  k
  375. /*                                                                                                                                                */
    1 }& c1 d1 D$ h$ B: a9 Y
  376. /* This procedure writes a byte to the Status Register.                                        */* u2 v/ x. R: Q
  377. /*                                                                                                                                                */' f9 f$ e2 S/ `) e: y7 \- j
  378. /* Input:                                                                                                                                */9 U, u: @( C! r, W
  379. /*                byte                                                                                                                        */' u; J$ W. u7 U& a
  380. /*                                                                                                                                                */
    ! b# Z* d3 Y; L
  381. /* Returns:                                                                                                                                */
    , T0 t' c3 s: K, D1 @: ^
  382. /*                Nothing                                                                                                                        */5 F* w$ A+ P) L: I7 l2 @9 M( n
  383. /************************************************************************/
    ( G6 |0 R( G& e9 F# ?+ \& I
  384. void WRSR(byte)
    . m  e. a+ [% k' Q
  385. {
    % G: O7 s! e0 v* l
  386.         CE_Low();                                /* enable device */! @% O$ T- N1 m8 ~" D
  387.         Send_Byte(0x01);                /* select write to status register */$ B" z2 ^# k' r" C
  388.         Send_Byte(byte);                /* data that will change the status of BPx * Y3 c3 O% I. C# F& s6 j+ e7 b
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    ! {% K& C+ z2 \0 P6 M; I
  390.         CE_High();                                /* disable the device */
    2 ]) E  H7 A, V; X
  391. }
    - k/ @2 b1 T9 T9 C, M; F' c
  392. 2 S9 c8 b# [8 d, ~8 d  J
  393. /************************************************************************/( N. U; y/ v3 d
  394. /* PROCEDURE: WREN                                                                                                                */
    " i4 i7 l) t  Y6 T% I0 @6 Z' F
  395. /*                                                                                                                                                */
    ! D1 w8 p- K) ~8 o' w" |+ t
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */9 d7 {' e) I. x. V2 f: c
  397. /* to Enables Write Status Register.                                                                        */
    ( P& F8 {" C* t7 l7 H# O8 x
  398. /*                                                                                                                                                */
    . [% V0 I$ I# s9 b) o# N: K
  399. /* Input:                                                                                                                                */
    + z' K! l# m" i& z& K& F% T
  400. /*                None                                                                                                                        */2 i+ ?( g  T1 e& Z$ [8 `
  401. /*                                                                                                                                                */
    7 i- D/ v8 X+ V/ ?6 E' a
  402. /* Returns:                                                                                                                                */
    5 p$ c) S( E$ y9 r( X3 d8 M2 P
  403. /*                Nothing                                                                                                                        */% {' R' {3 `/ K) O' U6 l" c4 g
  404. /************************************************************************/
    : c3 h8 H6 {' {1 Z" j/ c8 ^- B
  405. void WREN()
    & ~  H' B- u/ R0 k' j$ A
  406. {# A' |$ O1 {0 E
  407.         CE_Low();                                /* enable device */# M! L! G6 J! e/ S4 u$ q
  408.         Send_Byte(0x06);                /* send WREN command */1 f1 t# c* x" C$ l. E3 |# N: ]
  409.         CE_High();                                /* disable device */1 }. U1 d1 C% L6 E& D0 w
  410. }+ ^' |) [6 r: ?# s. Y& I

  411. # k, b1 J- @- H( S" A6 i8 C% S
  412. /************************************************************************/  h1 ?/ A5 S& I( z6 o
  413. /* PROCEDURE: WRDI                                                                                                                */
    8 A. z/ `0 n# ~
  414. /*                                                                                                                                                */0 A8 f0 o" |$ }0 Z1 z( I
  415. /* This procedure disables the Write Enable Latch.                                                */
    & [; l; q: f& H& F& Z
  416. /*                                                                                                                                                */, T1 C- p  }$ w9 |  p& i
  417. /* Input:                                                                                                                                */# H2 o2 ?. {3 M. o8 C6 ]1 J
  418. /*                None                                                                                                                        */2 x/ ^* G  n, `  K8 M
  419. /*                                                                                                                                                */
      i* K( ~6 j8 b/ q( b) z
  420. /* Returns:                                                                                                                                */8 Z8 R' Q1 q7 _& f
  421. /*                Nothing                                                                                                                        */
    7 I' r3 ^; U4 u4 G
  422. /************************************************************************/
    , m% }  c0 p5 j) S8 z7 q
  423. void WRDI()
    / R7 s5 M& U# i& [2 z$ a. n6 J
  424. {
    2 F, A- x0 {) S8 S# U) E
  425.         CE_Low();                                /* enable device */: O. R' Q! P( ]4 f" M' p" P
  426.         Send_Byte(0x04);                /* send WRDI command */& Y# l2 O8 k8 X2 g& s0 m. L
  427.         CE_High();                                /* disable device */
    ; ]8 P. N3 Z7 U+ v! y( F% P! T
  428. }8 W/ d+ r7 m( x/ T: m9 ~5 o1 N

  429. / w* z! I9 k) W% x% c
  430. /************************************************************************/
    : K; a  T3 u' `
  431. /* PROCEDURE: EBSY                                                                                                                */
    2 |1 o, _5 {+ ?3 U& j
  432. /*                                                                                                                                                */
    : P: F! V; B3 p* Z
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    / V6 H. `" Y% m! l
  434. /* programming.                                                                                                                        */: E3 R, b0 s2 x5 l8 s  L6 d- z
  435. /*                                                                                                                                                */. Z7 k& S7 Z- }+ @/ x
  436. /* Input:                                                                                                                                */
    ( L8 K0 Z2 N  J- w2 W! f
  437. /*                None                                                                                                                        */
    3 Y( C8 ?% p+ r6 J
  438. /*                                                                                                                                                */
    . w9 }. y: r0 {& l3 I9 u
  439. /* Returns:                                                                                                                                */  p) J7 f& B8 s6 K& ~
  440. /*                Nothing                                                                                                                        */' n6 K/ C- a* |* Z
  441. /************************************************************************/
    8 }4 m6 c8 n) v8 z: @, Q5 S; P; Y" Z
  442. void EBSY()  I1 [3 @$ M# k5 d
  443. {1 u- ]0 {; P4 F0 D) }4 [
  444.         CE_Low();                                /* enable device */+ R9 ^8 [5 W' N" r, c7 w5 e# Y9 J  k
  445.         Send_Byte(0x70);                /* send EBSY command */
    4 X/ I* s6 x( @% V+ x0 K9 ]# l
  446.         CE_High();                                /* disable device */1 |' O) n$ D0 v5 B
  447. }8 U. Z0 D3 y; @- T3 y

  448. 3 \) X9 G6 R& d/ @- ?
  449. /************************************************************************/+ J, u6 N* a  b- }" s
  450. /* PROCEDURE: DBSY                                                                                                                */
    / H3 b) D5 E! J
  451. /*                                                                                                                                                */
    9 v  r# \) |7 o& e
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    6 F. K9 T7 O$ A, [3 E( B4 z. \
  453. /* programming.                                                                                                                        */$ K/ |. A' i4 ?* O5 ^5 Z
  454. /*                                                                                                                                                */# _" b2 _* b* M. g3 ]1 ]
  455. /* Input:                                                                                                                                */2 ?6 Q' P. T" C% d. ?& Y. M
  456. /*                None                                                                                                                        */
    # B: n3 F5 I( b, A8 R
  457. /*                                                                                                                                                */- x) M" ]6 s1 Q
  458. /* Returns:                                                                                                                                */9 r+ d9 I9 q  }- c2 T6 F
  459. /*                Nothing                                                                                                                        */
    5 ~/ [$ x4 _7 ^
  460. /************************************************************************/: z9 V- n- p* U
  461. void DBSY()
    7 R3 C# H) y; T6 z# s; |9 Z
  462. {
    5 r8 B, |+ O! G  Z
  463.         CE_Low();                                /* enable device */$ v" n$ C/ Y# d  `
  464.         Send_Byte(0x80);                /* send DBSY command */
    " q7 [3 c. c* [
  465.         CE_High();                                /* disable device */% m9 q  m1 T6 J6 P% n. v0 S: R( [
  466. }6 r+ a4 F$ G# O5 {* h
  467. / |" [- ]( v. U0 t4 l8 }
  468. /************************************************************************/$ V) w) {" }1 h" _, ]/ {! u  l( E; f
  469. /* PROCEDURE: Read_ID                                                                                                        */
    / W4 D8 [( V# @" J$ e& k2 N
  470. /*                                                                                                                                                */
    1 Q" A) I! E& ]$ q, p1 |+ L
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */% o/ W# r+ U. {0 u& o; e8 @
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    3 T0 P2 _: D% Y$ p+ o6 ]
  473. /* It is up to the user to give the last byte ID_addr to determine      */) {2 d2 J! N& ^
  474. /* whether the device outputs manufacturer's ID first, or device ID         */* C$ k  \$ X* ^7 j6 T# c" |$ _3 n) k- d
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    1 c# Z& A; y7 C  S) s
  476. /* variable byte.                                                                                                                */) a% F  }( G4 T. D
  477. /*                                                                                                                                                */9 s# S4 _  x. s1 v$ ], w
  478. /* Input:                                                                                                                                */3 Q/ m% j, o: }9 p$ f' i/ Z
  479. /*                ID_addr                                                                                                                        */0 S9 a! W8 M2 |4 G4 Q
  480. /*                                                                                                                                                */
    , j3 {- q& F- \$ B" Q, ]) p
  481. /* Returns:                                                                                                                                */
    . K3 ]) V- g# J4 ], s0 z8 A
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    * \5 K5 o! X" g, e) U1 P+ X
  483. /*                                                                                                                                                */
    6 j; o3 C! e. {' d( |3 F6 i
  484. /************************************************************************/
    * _; x  t( I, \* ^1 G
  485. unsigned char Read_ID(ID_addr)0 w0 A" Z: L6 J( d. I% E& [. P: v
  486. {
    4 R: {1 o$ p3 r  y3 ^  S
  487.         unsigned char byte;. ^  i4 k9 Z" W& n: E
  488.         CE_Low();                                /* enable device */
    , O" _+ u+ T( Z$ l
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */8 U7 C% n, t; s  s$ c4 ?3 d
  490.     Send_Byte(0x00);                /* send address */
    : {. H: Y& d* H, {' h, D
  491.         Send_Byte(0x00);                /* send address */
    6 N# ]& `+ U+ {( j# w
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */) w1 p5 c6 [/ Q
  493.         byte = Get_Byte();                /* receive byte */- t8 r: n8 o$ R0 u
  494.         CE_High();                                /* disable device */
    * x0 y  x; D, d5 j
  495.         return byte;
    # u9 p' Q" E$ c" L) g6 L& ^
  496. }
    ! B2 f( M4 N" f/ H; F
  497. # f' k0 y1 j5 c
  498. /************************************************************************/
    3 ?% v. V1 a! P' A7 y
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */) ^3 r  H( A, p/ a: y9 Y5 @- q) c
  500. /*                                                                                                                                                */! P7 @4 ~; G) n1 ]
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */5 S9 I( b+ H& y+ ?
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    7 M3 F) D0 T' @# _# A! B( h  I
  503. /* Please see the product datasheet for details.                                                  */
    ) w( `! i. t2 q7 B" q
  504. /*                                                                                                                                                */8 R* F2 d+ p% E1 e! T; l
  505. /* Input:                                                                                                                                */
    4 }8 Y( h' p! m5 B
  506. /*                None                                                                                                                        */8 e2 c& [5 E$ i* S" `
  507. /*                                                                                                                                                */4 y! f  r2 g5 c; E5 H; s
  508. /* Returns:                                                                                                                                */
    4 i5 y3 y& a) m7 c+ X
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    $ l7 Y! |, u: k
  510. /*                 and Device ID (8Eh)                                                                                        */
    & ?7 P" L# X* l- i7 P# C, V
  511. /*                                                                                                                                                */
    6 f0 i  J% A5 r4 z; Q
  512. /************************************************************************/9 h. R9 b+ x# A. Y! W
  513. unsigned long Jedec_ID_Read()
    ) e8 b9 {& I) f9 w+ g3 Q0 L
  514. {
    . j; ]- D0 Y: v+ M6 N! v
  515.         unsigned long temp;! R- e" Y- w& F1 h
  516.         9 W: n' N& ~5 I6 t  G/ r) ?+ e7 W
  517.         temp = 0;
    9 r. r$ b1 D  U

  518. " K  l+ R& F- Z
  519.         CE_Low();                                        /* enable device */  c( \- p- s2 _, m/ o
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    - d# F5 F2 z9 D1 x6 m
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */, c6 q; @/ E4 `% h
  522.         temp = (temp | Get_Byte()) << 8;       
    . z+ H& w! h; a& ~
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    8 l5 F. F7 n# |2 a6 U0 j4 f
  524.         CE_High();                                                        /* disable device */
    " S" c( j2 J0 {) m

  525. ( T& z: }/ ]! S. s0 {8 v' G
  526.         return temp;
    ( A* R. `% d/ n: X( G: e5 `$ M
  527. }( a/ X. c$ b6 `& ~( D; B/ D

  528. 8 `9 L$ l% J( N7 H3 m
  529. /************************************************************************/* c" x3 n" N! p+ w8 C' V
  530. /* PROCEDURE:        Read                                                                                                        */* `* S$ s) c! [( }0 r
  531. /*                                                                                                                                                */                4 ^& s! j2 l# B! ?
  532. /* This procedure reads one address of the device.  It will return the         */
    . V: ]* N5 o" d$ D. i/ N* o5 |3 O3 V
  533. /* byte read in variable byte.                                                                                        */5 e3 _& q3 ]6 K# f- J
  534. /*                                                                                                                                                */* D. ^/ V% R6 g& g7 R# \& J, @
  535. /*                                                                                                                                                */2 D: i% u4 O7 c+ T  n
  536. /*                                                                                                                                                */; q* ~. D* i+ G% k* Q
  537. /* Input:                                                                                                                                */
    " x8 Z) U9 ^  p, j
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    7 }( L, I' W2 w7 q
  539. /*                                                                                                                                      */
    ; a8 A" ~" a6 ?1 O" b
  540. /*                                                                                                                                                */
    : o( u& L% z* _3 P" }( C% k0 L# u
  541. /* Returns:                                                                                                                                */
    % q% J  v, B" C7 H1 K
  542. /*                byte                                                                                                                        */: a$ _  ]3 P3 @
  543. /*                                                                                                                                                */& ~! f3 b' p8 p4 I8 n( {
  544. /************************************************************************/! Z% b$ v% `0 w/ N# y' V* P2 \) ]2 W
  545. unsigned char Read(unsigned long Dst) 6 }3 D* z# L. u8 l$ E* e# q  c
  546. {
    ( ~. O) e) q+ y; c% }, u8 y: J* _
  547.         unsigned char byte = 0;        & Z1 w* _" O. B! F2 Y

  548. % [3 @: Z% F/ H4 I$ f$ c4 g: q$ `
  549.         CE_Low();                                /* enable device *// i: r3 g. C9 y' O
  550.         Send_Byte(0x03);                 /* read command */6 K8 a7 N2 ~0 T3 k9 B! f9 W
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */7 p0 L  ~! Y; O7 l$ p
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));* b- u! K) I  I  U! V6 E
  553.         Send_Byte(Dst & 0xFF);
    4 R4 C0 ?* N9 i' f: A) m+ x
  554.         byte = Get_Byte();
    * ~& P3 }! V9 `$ f5 N% O: y
  555.         CE_High();                                /* disable device */  l9 `# x) }% t+ H
  556.         return byte;                        /* return one byte read *// O& B- g6 |& R& t
  557. }
    . [& A$ V6 H9 K( @  h3 a2 X3 \

  558.   w% M  h3 `2 L" l+ B4 K
  559. /************************************************************************/' P' [; ^) z1 @4 _' }
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    : C4 r/ v$ y% M, u+ V6 u
  561. /*                                                                                                                                                */               
    , J" ?+ S/ U, r" e
  562. /* This procedure reads multiple addresses of the device and stores                */! S2 ~8 D; t% [" J1 z
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/) m: d) N& d* t& o8 |
  564. /*                                                                                                                                                */  Y" l; }% \9 ?. Z6 T
  565. /* Input:                                                                                                                                */
    + X, S8 D+ y' y$ K8 W$ d
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    8 M& D2 W- S% X
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */1 X/ p4 K. V5 |8 D
  568. /*                                                                                                                                                */
    0 M) P4 A& x8 H! R
  569. /* Returns:                                                                                                                                */) j8 a1 h; u( c0 }# P
  570. /*                Nothing                                                                                                                        */0 s. z# c7 x! [4 ]& @
  571. /*                                                                                                                                                */
    ' U% U- h+ v4 Z# L6 m
  572. /************************************************************************/% Q  R4 l- F- q& C9 K' n) c
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)$ v) X" ?" V+ @) D% G6 [0 Y3 x1 v
  574. {
    ' z% V% T& D0 Q$ h" C( ~) g4 F. G
  575.         unsigned long i = 0;' {8 ^( K- q$ t% L% Y9 u' U; ^
  576.         CE_Low();                                        /* enable device */
    " \3 \3 K: b; k& O3 G9 y5 J
  577.         Send_Byte(0x03);                         /* read command */
    $ _8 b5 ]0 F8 ^2 A/ Y
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */1 a* B' G, c3 @$ n  F5 i
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % F# o0 m" q1 I# X
  580.         Send_Byte(Dst & 0xFF);
      P; Y, ^& {; Q  a' {
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */- m4 K* v4 H& H/ L/ t  \- ^
  582.         {
    , u7 X! F2 A' M( Q6 [: V; e
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH *// X% L4 l* S% Y1 ~' s
  584.         }$ _- _7 A7 P$ U. m1 K" C# c
  585.         CE_High();                                        /* disable device */
    2 H& i: @1 _" A: N: x9 z
  586. 6 l- O7 z0 ]7 u" _
  587. }0 R7 R, i( _" J8 W' J$ v

  588. - A! Q" ~' h8 _- ?
  589. /************************************************************************/
    , v5 t8 l1 y$ W6 U
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */" Q  M- z! J' ~! z8 X1 r8 Y
  591. /*                                                                                                                                                */                ! b+ c. g& h: s. z* L: `
  592. /* This procedure reads one address of the device.  It will return the         */
    7 W7 y! p9 p# ~4 F
  593. /* byte read in variable byte.                                                                                        */; ~/ R1 X* ]# N0 V
  594. /*                                                                                                                                                */- x2 c) R. I) P  z
  595. /*                                                                                                                                                */
    7 n$ l7 x( _$ V1 v
  596. /*                                                                                                                                                */8 d3 f+ O6 s7 _( o9 C/ ?. ?0 U
  597. /* Input:                                                                                                                                */
    7 o+ j1 K* v& w) l: N0 E
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */& a- x* r" {7 _$ |4 d
  599. /*                                                                                                                                      */
    0 C: a7 [; |! T/ j
  600. /*                                                                                                                                                */
    0 e: q+ B( ?* J
  601. /* Returns:                                                                                                                                */$ c+ J* v3 D) D' p3 l5 g0 k
  602. /*                byte                                                                                                                        */$ ~5 L* \6 f* t2 L7 U0 s
  603. /*                                                                                                                                                */
    8 }+ R& @, \+ q+ E+ X
  604. /************************************************************************/* |' [- Y5 O  Z5 B/ |$ c. `
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    5 y8 Q- X/ W+ I8 G0 x3 ^. d- p
  606. {6 u8 D. g0 {  ^  ~- c, E3 ~6 e
  607.         unsigned char byte = 0;       
    6 L& _# b; E8 g2 ^
  608. 8 ~1 S' S/ k. q
  609.         CE_Low();                                /* enable device */, I. G' e% Z5 \% C( E
  610.         Send_Byte(0x0B);                 /* read command */: b! e9 O. T; Y& }- q1 ~
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    2 U, H; I( m2 n
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));# Z/ T: e- X# d* W  Q1 k8 e1 q+ |6 @
  613.         Send_Byte(Dst & 0xFF);5 [/ r4 a1 x& o: h5 a" w
  614.         Send_Byte(0xFF);                /*dummy byte*/% b) B" v8 q2 C. Y/ s" @* U
  615.         byte = Get_Byte();$ }& l. J. U: `8 F0 ?: t3 T
  616.         CE_High();                                /* disable device *// z( v  F6 n: w  l. _: w
  617.         return byte;                        /* return one byte read */
    * q# l3 O1 T; ^& t* h8 q( r
  618. }
    # |$ E% @+ r- s* `
  619. . ?* q/ x- W( `8 b7 X& e: P
  620. /************************************************************************/3 i* Z: c' i( Y4 B8 A: i4 t+ q/ X! B
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */) U' u. F  e) U) b  _
  622. /*                                                                                                                                                */                  q: B9 T! q9 _) L
  623. /* This procedure reads multiple addresses of the device and stores                */
    ( O- t) d: H4 y2 @- X1 a6 N
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    3 s! [  m" \* e+ x$ k7 b
  625. /*                                                                                                                                                */
    / a. Z( d; Z. r5 \
  626. /* Input:                                                                                                                                */
    : [  F/ w) J1 Y) d5 j
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    - N/ p; b8 ]/ B2 F
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */3 r( C' q9 ?% g; k8 Q6 U  r4 }" D
  629. /*                                                                                                                                                */; X2 l8 X; U7 X! t
  630. /* Returns:                                                                                                                                */
    1 f) z9 T9 e! v3 ?
  631. /*                Nothing                                                                                                                        */# k5 x- ^, m. k, K
  632. /*                                                                                                                                                */
    ( W+ |& Q. U. k8 c: V9 @9 d( R
  633. /************************************************************************/  k7 O# ^5 k, b/ M  j
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes), `8 V! R6 d1 }8 G
  635. {. y; K& r- ~* _8 N! v- H4 P
  636.         unsigned long i = 0;
    ; H4 G6 B6 ^1 r4 V, D/ o, d
  637.         CE_Low();                                        /* enable device */
    ! d  J5 p! t0 \# N8 c
  638.         Send_Byte(0x0B);                         /* read command */
    2 n* ?% m" @. E: j, k- g4 F. T
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */5 c  U! T4 Y4 |. ]
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 Q7 f$ a9 w" f* }: `9 {. O
  641.         Send_Byte(Dst & 0xFF);! W  v( B- I% X7 T3 [
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    # P) q3 @& A( m
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    . }2 x& o- s  L
  644.         {
    & g  w  `* V6 F& c3 S
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    ) x3 m+ Z' F4 T! Q0 T" _9 A
  646.         }! k2 j* `/ ~7 E  @" t; u
  647.         CE_High();                                /* disable device */; c- b6 s" x6 u4 y! F
  648. }
    # p/ h3 @0 U* P+ M- N

  649. 6 d9 N  F6 e: I' j  q7 ~: `, r
  650. /************************************************************************/6 F' ?  y: {- p/ A
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    " `0 C$ @$ ?+ W3 j
  652. /*                                                                                                                                                */
    $ G& @+ Y8 |4 m+ A5 Q- d+ t: [( n
  653. /* This procedure programs one address of the device.                                        */6 Y, b: B' ^. H6 [
  654. /* Assumption:  Address being programmed is already erased and is NOT        */6 c( I0 x# K7 r9 s7 ^3 x/ K0 a6 R
  655. /* block protected.                                                                                                                */
    : _; g5 ]" e: \  j( I4 l  C# S/ A
  656. /*                                                                                                                                                */
    6 l& P' F1 ~& c2 f0 K9 w' `) [
  657. /*                                                                                                                                                */2 c5 z+ Z( n! m9 @
  658. /*                                                                                                                                                */' n+ c* r& O  X; k9 u: p
  659. /* Input:                                                                                                                                */5 I* x) y- C7 D
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */( ]6 R! A7 v& o2 o" e: M9 l
  661. /*                byte:                byte to be programmed                                                                */6 H; [* Q. J) d0 k% i
  662. /*                                                                                                                                      */
    : I* _3 E$ u6 Y
  663. /*                                                                                                                                                */
    2 r; j  w/ H/ P2 t3 ^" z2 l
  664. /* Returns:                                                                                                                                */8 v6 I5 d0 t. d& S2 G
  665. /*                Nothing                                                                                                                        */) v% B- p) S8 f; X% e
  666. /*                                                                                                                                                */
    / C  o5 \2 v- E% P+ L% F% C
  667. /************************************************************************/
    % |/ H# x6 x& V, Q' p( E
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    ! @# O6 l% z1 t# [
  669. {
    ! N& ~; r9 {+ Q0 I
  670.         CE_Low();                                        /* enable device */
    0 o7 Y1 i: G. `! G
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    1 ~+ a! ]; \" k' d. B: m
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */: E/ H* P$ @7 y1 E, d( Y
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    . l1 P+ v9 g: _
  674.         Send_Byte(Dst & 0xFF);
    " @7 x* T' z2 @2 j7 w6 O3 R5 x
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    " C& h+ t4 ^/ O1 C4 n- t
  676.         CE_High();                                        /* disable device */
    % f5 j3 K, ~8 A
  677. }" N: D# z: l6 z6 r

  678. # H+ B5 q  _; g' c/ [9 [
  679. /************************************************************************/
    1 T% i6 H  g& ]# r4 Z
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */+ E* i$ w5 H. F2 n1 d6 S* O1 a
  681. /*                                                                                                                                                */
    3 ~8 i) H: \+ [
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/% G6 Y% K  B$ m( W3 b+ p
  683. /* the device:  1st data byte will be programmed into the initial                 */
    ( m3 {& B0 e8 Q
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */$ h, c4 k" L5 n
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */2 F; D/ R: Q, E& B$ f
  686. /* is used to to start the AAI process.  It should be followed by                 */
    - W8 n3 G& |+ {* [- z
  687. /* Auto_Add_IncB.                                                                                                                */4 `% b9 f; C$ b' S" j6 j2 [
  688. /* Assumption:  Address being programmed is already erased and is NOT        */9 i7 Y/ P% k% F4 @) A) \: \
  689. /*                                block protected.                                                                                */
    9 a! q+ }( k4 E) q; q
  690. /*                                                                                                                                                */
    ! J' ^. I% O- p3 {$ Y: B
  691. /*                                                                                                                                                */
    * M* o' K1 H. A% \
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    4 b  I* K0 s# q% Z" t, {, E8 P
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */' Q6 H( |* `: R! Q
  694. /*         unless AAI is programming the last address or last address of                */
    0 X# k- @! W5 u# u8 h
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    * U: p/ |; O" B& C( e8 K
  696. /*                                                                                                                                                */2 L. v! }: A9 O) r, M# F
  697. /* Input:                                                                                                                                */; i6 O7 m' G. f/ k5 B, |
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */4 B: B- [4 m1 G3 e, R" @
  699. /*                byte1:                1st byte to be programmed                                                        */
    ' j9 C& h4 }) ^7 Y0 I  a# K  x
  700. /*      byte1:                2nd byte to be programmed                                                        */" i# C* B4 m0 s! f8 ?. @
  701. /*                                                                                                                                                */
    6 ]! o! c: z& c% G9 K) c
  702. /* Returns:                                                                                                                                */2 F! @0 w  m( f, R* {
  703. /*                Nothing                                                                                                                        */
    0 n( i  Q& }4 L! h8 l' o$ D
  704. /*                                                                                                                                                */6 O% [$ T/ q1 f; Z4 X
  705. /************************************************************************/% c: G; q' O  V: V
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    6 X8 v1 I) R+ Q# D
  707. {
    " j% K& y% ~; T2 }2 ^3 Q
  708.         CE_Low();                                        /* enable device */
    8 D2 R3 U1 }6 @" Y  a
  709.         Send_Byte(0xAD);                        /* send AAI command */1 s2 b0 J5 p5 a0 Y- V' u5 b
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */2 e$ u( R) `3 S
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % C$ o8 Y% c% V! v& y. L5 G
  712.         Send_Byte(Dst & 0xFF);, j0 ~6 S: {8 |* Q# N; r
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    + `! g% ^- J' E9 l% t6 w
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    2 ?: @: U; f. p; P7 m  v! u, I
  715.         CE_High();                                        /* disable device */
    / ~& A) ?* T6 N- W
  716. }
    ! |: g( B+ t" n

  717. + B" B3 P' L% a1 b5 s) K" d# i& z
  718. /************************************************************************/
    0 T2 l* }- G: H. q& E) s/ v$ c+ F
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    - i' E4 u/ A* S3 }
  720. /*                                                                                                                                                */
    : f+ }8 N- j2 P( K
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/. i8 V8 j  X7 j
  722. /* the device:  1st data byte will be programmed into the initial                 */
    ( C& `. Z4 S6 Q/ U% S
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    . E# U& Z5 {2 h! u
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    0 a" Z* A1 N/ i- A/ c
  725. /* is used after Auto_Address_IncA.                                                                                */7 y( S! K7 E# u0 y
  726. /* Assumption:  Address being programmed is already erased and is NOT        */6 u$ E3 u6 E* p2 e6 v
  727. /*                                block protected.                                                                                */. W. l5 t) M3 ?" N9 }  O$ A
  728. /*                                                                                                                                                */
    5 O( m- u1 e5 B6 H
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */! O7 `& |5 F1 |8 ^
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */1 V' V, i4 ^/ l  [
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    9 \( g4 x& u1 X
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    ( U) j; P2 `- W: I7 j
  733. /*         last address of unprotected block, which automatically exits                 */
    & N8 ?- E5 u5 z3 _4 j
  734. /*         AAI mode.                                                                                                                        */
    ! Q" g2 L% C4 a: R" x3 B* U
  735. /*                                                                                                                                                */
    9 r' N7 h/ I5 R6 R
  736. /* Input:                                                                                                                                */3 j) B$ s1 |8 {
  737. /*                                                                                                                                                */
    0 j  y4 ?6 @* k, l7 @# v6 x! E
  738. /*                byte1:                1st byte to be programmed                                                        */
    7 j- _/ A" x$ A& c/ _( n6 d
  739. /*                byte2:                2nd byte to be programmed                                                        */2 t- K9 L+ q0 @+ c
  740. /*                                                                                                                                      */5 p1 G. X) Q; E; i
  741. /*                                                                                                                                                */
    2 D5 P- n0 o3 H6 j: d( S+ f. A- L; H
  742. /* Returns:                                                                                                                                */
    1 b+ N  A8 c8 I
  743. /*                Nothing                                                                                                                        */
    ) ~( g* f  G, f  L0 q% |7 ]* q
  744. /*                                                                                                                                                *// X4 F% H6 Z) t: g7 t, g. n( r
  745. /************************************************************************/4 W, w( e2 d$ f6 @5 v1 z2 w
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    $ ?% p2 F3 L' W, @& T1 m
  747. {6 Y1 L! g9 P0 k
  748.         CE_Low();                                        /* enable device */$ {! |6 ?2 y# n% i1 F1 p
  749.         Send_Byte(0xAD);                        /* send AAI command */
    8 `1 ]' H$ o3 J9 H0 p8 k( C
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    4 u# y) Q" \6 n2 D4 x
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */: I3 Y9 e1 z9 r
  752.         CE_High();                                        /* disable device */
    ' }9 G: E1 {* j9 O' t! d# Z$ i. H
  753. }
    7 x' f( a; m2 E, L0 D2 o
  754. ' d3 T4 y7 J) H8 g/ j
  755. /************************************************************************/
    , d1 O" X  ~9 r! b
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    0 a0 ]' l$ N2 {3 x
  757. /*                                                                                                                                                */
    7 e! }' c3 N4 P# _/ S
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    % f* s& l" ~6 z1 s- f
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */# i& V% u! \* i
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */: R5 X  d% Z& N8 t. p0 x
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */$ l  l, e6 @$ e  U6 S+ r& N: X) M
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
      R2 X$ q, u) O4 F* K7 t. V
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */. N: t. S: [4 I- j3 |
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    + P3 @, V6 {9 M" P4 y
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    ' J; s$ Z! o. y
  766. /*                                block protected.                                                                                */7 N4 f% Y: D: p0 S# N; ?
  767. /*                                                                                                                                                */4 l) u( _3 A0 i& q
  768. /*                                                                                                                                                */" s2 B( u8 |. M) @$ U- f0 s, N
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */  Q% t! r/ x- O$ d8 Z
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    5 \+ \) B" }0 ^1 A: G& _
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    * ?) W7 u/ E% P/ m% J8 e- s
  772. /*          to exit AAI mode unless AAI is programming the last address or                */# t: B" M( o' U0 q! |
  773. /*         last address of unprotected block, which automatically exits                 */5 y8 i1 S. c# j1 d6 q
  774. /*         AAI mode.                                                                                                                        */
    ( {+ w9 g2 i% x# F9 s5 o$ A
  775. /*                                                                                                                                                */; f9 A+ b1 n6 `  X# O
  776. /* Input:                                                                                                                                */' X( \: {& X/ F1 ~
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */* x3 E8 h# i5 U9 r. F- _* \
  778. /*                byte1:                1st byte to be programmed                                                        */
    # R0 U9 r& m4 C$ u6 C: O, \
  779. /*      byte1:                2nd byte to be programmed                                                        */6 e$ }9 |+ L6 L, \2 Q4 [$ y
  780. /*                                                                                                                                                */7 A; L7 T1 F( X# r$ q
  781. /* Returns:                                                                                                                                */
    " C* |+ a% |0 x9 M4 a5 @
  782. /*                Nothing                                                                                                                        */
    - p1 I( v: ]& u1 G; X
  783. /*                                                                                                                                                *// `2 d: `6 V, f, B+ Z) T
  784. /************************************************************************/
    " c9 @/ Z) L' I, _. A
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2): }) p8 P% z5 N4 Z5 G, h# e- [
  786. {
    . A+ u4 O1 x* y  A# R5 e- O" f
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    # C  l& F( p3 |+ E) D& y
  788. + p5 l2 y# o% A, U
  789.         CE_Low();                                        /* enable device */+ \, ~: u. T6 e
  790.         Send_Byte(0xAD);                        /* send AAI command */+ x5 B1 W( V& w6 a3 y* H1 b
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */$ q! y* s, j% R$ S5 _/ t8 A
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));% b* ], }, I! `# q" B% S
  793.         Send_Byte(Dst & 0xFF);% K* W  I  D/ X2 H; I' v2 b0 f# P
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    : _; o1 c! y6 B# t. b) d% e& N0 P4 L
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */3 M7 ~  ]- w& B% F" n8 Z
  796.         CE_High();                                        /* disable device */
    + Q7 |  V  m4 \/ p; p' c! n+ Y
  797.         & h& q; _, Q( A  m: G( i% b. T+ \
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */* l# k' T, f1 i9 r- a/ Z, S
  799. ( L/ t" n; D- W# r
  800. }* Q( b& R' S, U) {* i$ o8 R

  801. - I. P# }! A( v* s6 C
  802. /************************************************************************/
    . [6 p* C  `* K6 |
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */2 H5 h% _; ?% [2 R( u8 @1 g& |4 S9 _
  804. /*                                                                                                                                                */2 I" r2 w3 L$ d! ]
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    3 P6 o4 ]5 l7 c! b
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    + a2 K" `+ P& `$ _
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    - j+ o! p" Z' n  W3 Y9 z
  808. /* the device.  The 1st data byte will be programmed into the initial   */5 Y: r! G! X. q- E! p1 ^
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    ( r$ c+ z  ?# s0 z
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */+ j' Y/ u( E) N% ^( J
  811. /* used after Auto_Address_IncA.                                                                                */. ~% ^- G% \3 J0 }- v
  812. /* Assumption:  Address being programmed is already erased and is NOT        */( C& S# `, Q. S7 f0 j+ a
  813. /*                                block protected.                                                                                */
    4 c: C. S# ]1 s$ O! b7 F' c
  814. /*                                                                                                                                                */! a6 c: m  B. f1 w% Q: ~
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
      e; L: I  q0 l0 \) c$ d- G' `
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */8 d4 j$ g3 U0 V& N. V
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    . `+ V* @  p8 j* {5 D  U( `
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    6 \: n& t! I. A; a) a3 n
  819. /*         last address of unprotected block, which automatically exits                 */; P2 t4 C: }) b+ j( P
  820. /*         AAI mode.                                                                                                                        */( B0 z/ L2 y1 H7 r4 h9 ~
  821. /*                                                                                                                                                */
    ! C8 F" G* P. ^$ i; {2 D
  822. /* Input:                                                                                                                                */
      V8 d5 p# H" o. V
  823. /*                                                                                                                                                */
      N1 n) ?7 @6 Q' Z, `9 o
  824. /*                byte1:                1st byte to be programmed                                                        */
    ! [. J; S1 l6 S$ M  q& n* P6 i+ d2 K. _, {
  825. /*                byte2:                2nd byte to be programmed                                                        */
    ' K) @& n1 O' b8 R
  826. /*                                                                                                                                      */7 G4 e+ m8 s" R2 V, z. R
  827. /*                                                                                                                                                */- \$ r. X7 \* ]
  828. /* Returns:                                                                                                                                */: s5 x+ \* `# g9 |' e( y
  829. /*                Nothing                                                                                                                        */
    ) {: Y* X- \% @2 q
  830. /*                                                                                                                                                */
    ) p( [6 V# [7 ?/ v: W( @" H7 @
  831. /************************************************************************/# H+ z- t  d8 Y. M/ t* `( p
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    ( R: d. [8 [% o, G3 z1 a8 |7 W
  833. {
    8 m* V8 v5 T, H, y2 j
  834.         CE_Low();                                /* enable device */
    . U, ]  f2 x8 ~9 Y4 b$ U1 A5 L
  835.         Send_Byte(0xAD);                /* send AAI command */
    6 I) d: p3 a! O7 ^6 j$ R5 B+ a7 ]: ]0 [
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    - A0 b0 Q) j9 k/ P
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    # N( i! {; H3 ^7 a: ], D5 x/ `
  838.         CE_High();                                /* disable device */
    ! u1 R* e  t1 g& q

  839. , \6 q, t& O1 U7 s* F
  840.         Poll_SO();                                /* polls RY/BY# using SO line */* v4 w6 q0 m8 u

  841. # a8 v7 h+ W' a, @, z! V" B# }% F
  842.         WRDI();                                 /* Exit AAI before executing DBSY */+ i3 B, x& ]# V
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    , T3 C& G( Z+ O: l4 z8 d
  844. }
    1 h. N9 c  b4 o  u8 T; t+ {
  845. 4 K- w  F4 x) S0 N% I
  846. /************************************************************************/+ s1 L& y* ?. y( s; `
  847. /* PROCEDURE: Chip_Erase                                                                                                */3 _0 D) Q8 q. M( L! b5 ?' w. F
  848. /*                                                                                                                                                */
    0 I' D! K8 u+ K; d& E
  849. /* This procedure erases the entire Chip.                                                                */! g) \8 e/ L6 Y$ l6 X. Q4 S! }
  850. /*                                                                                                                                                */% K) }7 g+ y5 J5 d( ~, g8 L8 T
  851. /* Input:                                                                                                                                */1 r  ]5 [% D, D9 {, c5 |
  852. /*                None                                                                                                                        */
    : B7 Q/ l/ b  M
  853. /*                                                                                                                                                */
    . D$ b$ R. k3 [, O) n! P3 a
  854. /* Returns:                                                                                                                                */% r. _! |7 J- Z7 q# @) s
  855. /*                Nothing                                                                                                                        */
    " v( p# P3 n! H. P% h* Z3 v1 _
  856. /************************************************************************/
    ) G$ d. X/ K0 ^% x$ n+ h5 Y! A
  857. void Chip_Erase()
    + E. b7 F' R/ g% A, Y* T4 s: q
  858. {                                               
    7 R% v1 o6 h  a) |$ U
  859.         CE_Low();                                /* enable device */
    % n2 p  t: A! b- h8 x
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    # ?2 q7 ~+ K: L" A7 T
  861.         CE_High();                                /* disable device */& P/ X3 |* V0 M. e( L  P  c
  862. }
    - `2 V- p5 s; P* T- t5 S7 J2 d$ S

  863. ; V  i' h- U9 [
  864. /************************************************************************/4 j" o5 T, X* D: ]' K5 G
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    5 z% I8 L4 x0 [- ~. J3 E9 B
  866. /*                                                                                                                                                */3 N$ m, @) E2 _( [9 _- R" C# w
  867. /* This procedure Sector Erases the Chip.                                                                */
    * ~: r% V& D4 z! O2 q
  868. /*                                                                                                                                                */5 G* _7 B$ x+ i9 M
  869. /* Input:                                                                                                                                */
    " G- U/ S6 |1 E% R9 G8 ?$ ~1 p
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */+ o# I7 ]  ^; W, S# Q) H- X( q( L
  871. /*                                                                                                                                                */$ T: l" n+ f4 U% Y3 |- D
  872. /* Returns:                                                                                                                                */2 s* x7 w( W0 {4 S8 F3 }- ^' @
  873. /*                Nothing                                                                                                                        */
    . \8 [' B- b7 h* _! U; a* }
  874. /************************************************************************/2 W- ?/ [: [, F: Y- A, W5 C
  875. void Sector_Erase(unsigned long Dst)# g% N& u' j7 ?. Y
  876. {" R) t3 `1 P! K# h7 S
  877. / p7 T: W" x) Z- j
  878.   w) F* Q) A( G4 F: u6 c, f! q
  879.         CE_Low();                                        /* enable device */* J) q2 D; h9 P2 {& v/ N0 }
  880.         Send_Byte(0x20);                        /* send Sector Erase command */% B! K# |6 _0 R7 v
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! M- ]7 C/ E6 r/ @. u3 T
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));% _" [* \) X: l" t
  883.         Send_Byte(Dst & 0xFF);7 Z( A0 e/ x3 t2 B2 p6 Q
  884.         CE_High();                                        /* disable device */* N6 v" t+ d( A
  885. }        0 N2 s# a0 i5 I+ C, j

  886. 1 |' C9 C+ A+ u% r7 C
  887. /************************************************************************/8 [7 L/ m* Q) l+ C  ]$ {/ Y
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    # }1 [: X+ P& t) m" R: z: n( F
  889. /*                                                                                                                                                */
    + e7 x0 i6 {2 [( W) a
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */: G. |0 P7 F: C1 P; A6 A+ ]1 K
  891. /*                                                                                                                                                */% @; j  p+ _  s. s3 v' w2 V
  892. /* Input:                                                                                                                                */8 S& S- i0 c- ?0 t
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    7 w+ R: C. K# M) u$ o( \  P
  894. /*                                                                                                                                                */) E5 h0 P9 P9 D% x* P
  895. /* Returns:                                                                                                                                */2 @! a( x) b/ ?2 `% h
  896. /*                Nothing                                                                                                                        */. _2 X# i+ Z! P8 u9 p  W
  897. /************************************************************************/
    ) [1 l  g7 O0 V* `: e$ _! M
  898. void Block_Erase_32K(unsigned long Dst)' Y6 t- f+ O1 h$ b9 W6 p# ~# D& |; |
  899. {8 ^4 s5 [" \* L' x* ~
  900.         CE_Low();                                        /* enable device */" Q0 {; Z+ ]( r9 R7 y8 z5 a
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */+ T- K) ~: \+ Q: O7 x* m/ R
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */4 G* X1 q2 j5 z1 F
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));. f9 o0 X, F! q& `
  904.         Send_Byte(Dst & 0xFF);
    : y2 d+ I! k4 m1 E! x/ n
  905.         CE_High();                                        /* disable device */- `6 N, Z- {' V. P$ _: O- w1 d
  906. }
    / p) V1 L5 g" ~! q2 q
  907. $ b+ |, s: A. h: C4 w* c) i
  908. /************************************************************************/2 s9 d/ ~9 i& Q( a+ W
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */, k" V$ F1 B- {& Z
  910. /*                                                                                                                                                */8 X5 i- x3 O8 K
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */3 ^# L5 Q6 O! W- O& N" d
  912. /*                                                                                                                                                */
    ) ?* b' F9 T- o* I( P
  913. /* Input:                                                                                                                                */* `% Q' I! o; a; |' F
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ! ^. n3 L- m- ]5 G# v) I
  915. /*                                                                                                                                                */
    1 q' E- S/ y4 S! e, Q  p+ b
  916. /* Returns:                                                                                                                                */# |; S$ F* Q8 _" @# `5 _
  917. /*                Nothing                                                                                                                        */( T; j1 C& y7 C
  918. /************************************************************************/: i7 A8 h3 R6 n# X$ t5 C
  919. void Block_Erase_64K(unsigned long Dst)
    6 u8 x2 S4 q9 a
  920. {) q$ z# |- j* Q6 u6 E7 x
  921.         CE_Low();                                        /* enable device */, T; f/ Q, {+ {+ d
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */9 t! `8 c9 S. g8 l; K5 _& p
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    3 j) b. `/ m* n/ ~# a/ e3 ~: u$ B
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));' d* _  b5 I8 v- P6 E: y
  925.         Send_Byte(Dst & 0xFF);
    : p6 U( X3 o# q' X1 p& H/ U  B
  926.         CE_High();                                        /* disable device */$ c+ z+ V1 w6 L0 O" U# D- b
  927. }
    & L  F) z4 i/ T" s2 i9 b
  928. , N4 e* U+ r6 R, t3 t3 y! ]: i, S
  929. /************************************************************************/0 p8 L/ I+ m/ \8 J- A( ~; U9 l% O$ T
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    ! X- U0 q% d- H
  931. /*                                                                                                                                                */
    ! h; \" M7 Q4 ?( L2 w
  932. /* This procedure waits until device is no longer busy (can be used by        */
      W$ O% y3 E( V* k1 l- ]$ L1 k; A
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    5 w! F7 T2 f1 ^
  934. /*                                                                                                                                                */
    1 k+ N# Q. W7 C5 k6 x/ M, Z
  935. /* Input:                                                                                                                                */
      i5 q$ |. F  _5 C/ ]& Y, Y
  936. /*                None                                                                                                                        */
    , C7 e" @* k4 T$ E% D; d
  937. /*                                                                                                                                                */
    & P1 I- d2 R# f
  938. /* Returns:                                                                                                                                */7 b/ e9 K& ~& e7 `2 K) I
  939. /*                Nothing                                                                                                                        */1 c3 Z/ I" y5 O7 T2 C
  940. /************************************************************************/9 g; y# g: w) H; o# ~, n% O
  941. void Wait_Busy()* ~6 A% j6 [* w0 u7 v& V+ B
  942. {- L! {* X+ Z" ]% H& i
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */" t2 f% B" t( b$ R
  944.                 Read_Status_Register();. a8 ]) L6 w  P. x1 V
  945. }
    , D1 R2 }4 }2 w7 E; I
  946. 6 I; i& O# c0 {: g, S1 ^
  947. /************************************************************************/& L) c2 m1 u% m4 m* _9 {* N
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */8 [; [" Q8 d+ n( ?' x' L+ ^/ `
  949. /*                                                                                                                                                */
    : m) i$ E; l! {: L/ V) ~! [" Q
  950. /* This procedure waits until device is no longer busy for AAI mode.        */  t; b, Y. @. r8 z3 [1 }
  951. /*                                                                                                                                                */
      B2 H6 Y" G. u
  952. /* Input:                                                                                                                                */
    6 l1 Y% j5 C7 X, N' U. \( `
  953. /*                None                                                                                                                        */6 T* M2 ]8 [2 {/ Y  C4 r9 N  f
  954. /*                                                                                                                                                */
    4 {0 E0 z8 G0 _2 m+ w/ e
  955. /* Returns:                                                                                                                                */
    / z3 x# Y# P: x$ D, T! l
  956. /*                Nothing                                                                                                                        */" r+ z1 W' t4 D% h5 Y: Y
  957. /************************************************************************/
    4 V) f/ w  `7 c/ b7 G
  958. void Wait_Busy_AAI()* i, A1 E, a  |# I# P' Y: D* A5 u* W
  959. {
      A8 p' W( s+ A  I% e
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    + o9 R: |9 X7 `# @$ a
  961.                 Read_Status_Register();$ P& e" f/ L) U7 z5 {6 Y. B& L- z
  962. }9 O% o5 l# g. K1 X8 J8 ~3 U! F. \
  963. + s% X0 S9 o% _$ ?, g9 J# E0 ?
  964. /************************************************************************/' q2 S' i( ?& }3 a
  965. /* PROCEDURE: WREN_Check                                                                                                */
    / o8 u- b; @! y) M8 E8 u- M
  966. /*                                                                                                                                                */
    ' v2 L, p$ M  t3 m
  967. /* This procedure checks to see if WEL bit set before program/erase.        */# V8 S+ C7 M6 ]# z- x& y% o: l: F
  968. /*                                                                                                                                                */
    & Q) g7 Z( Z7 F0 j1 P
  969. /* Input:                                                                                                                                */2 o0 Z6 ?8 u- n/ o; d/ n! {
  970. /*                None                                                                                                                        */
    . h/ f) W: Q7 q) w2 z1 N: Z
  971. /*                                                                                                                                                */2 s* X( n& \% n& j
  972. /* Returns:                                                                                                                                */" Q  q- N% |2 b; }3 h
  973. /*                Nothing                                                                                                                        */
    / G6 k5 S) `- `: x& Q
  974. /************************************************************************/, v8 {4 \9 V7 |5 R5 z
  975. void WREN_Check()  r# L$ e6 W# m8 Y  h- V0 M/ @$ p8 A+ p
  976. {( [# A( T; w2 g9 l
  977.         unsigned char byte;" P8 `0 f- |. @9 Y
  978.         byte = Read_Status_Register();        /* read the status register */( S! ?: W; f7 k$ E4 c
  979.         if (byte != 0x02)                /* verify that WEL bit is set */( O" H3 H( D1 Q6 U2 ~
  980.         {5 }- C) A6 q- c" z% \: x
  981.                 while(1)6 ?: |2 R# m0 ^" J
  982.                         /* add source code or statements for this file *// ?; v  _1 \- A3 z# A
  983.                         /* to compile                                  */
    0 f- r  b1 g* ]6 \) D
  984.                         /* i.e. option: insert a display to view error on LED? */
    # s9 R& C* s2 H" Z; b" z% l  p
  985.                  - x& m8 p, V$ F: h
  986.         }2 n9 R) v; h7 F# m& V7 B$ n
  987. }+ M% U9 i1 c; s
  988. % r/ j8 {* y5 W5 Z6 Z3 H& O9 ^0 ?! d
  989. /************************************************************************/3 p4 C+ M7 c" w
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    : e1 ]/ m1 X0 F5 d" A; O
  991. /*                                                                                                                                                */1 u- {& }8 X  H$ W2 \1 b
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
      O* g% W' r! k, k- X3 t& \% e; x  D
  993. /*                                                                                                                                                */
    ( r9 y. S& a0 S: e) m' j1 v
  994. /* Input:                                                                                                                                */
    0 G9 k. }' v" z0 G
  995. /*                None                                                                                                                        */2 t- A" a8 m: d+ c
  996. /*                                                                                                                                                */
    - B  P6 e4 ]4 h" O& o& L. `
  997. /* Returns:                                                                                                                                */
    1 g$ h1 ]$ r# b" i8 i
  998. /*                Nothing                                                                                                                        */9 }6 l9 w! ?3 Z9 j8 Q6 C! W3 P3 @
  999. /************************************************************************/3 w, V: \7 M3 H
  1000. void WREN_AAI_Check()
    6 q2 x* \, l- c% F  g" X
  1001. {
    3 ?9 r  r5 N" U) S) z$ u9 N
  1002.         unsigned char byte;
    0 ^; ^3 x/ S0 @- W6 i! u/ }- R0 f
  1003.         byte = Read_Status_Register();        /* read the status register */! p! d+ O+ C( h2 M6 V- t
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    5 y  Y/ T5 a. y4 b* t' h
  1005.         {- b, N. M% [1 P+ v
  1006.                 while(1)                8 y2 ?6 B) H. W9 K2 U
  1007.                         /* add source code or statements for this file */
    5 Q+ t1 }$ }+ @: y9 m  X
  1008.                         /* to compile                                  */
    1 n2 w+ ~$ j! T
  1009.                         /* i.e. option: insert a display to view error on LED? */7 s' x" x4 p- x. }% g
  1010. & k/ f5 \: P+ P) {/ |
  1011.         }" N1 a3 @: Q  e) X( O8 {! _
  1012. }6 {1 K4 B4 ~/ t5 G" f; t  u

  1013. 5 f, q- E4 H' g% D8 m* W
  1014. /************************************************************************/
    . t; D9 s; P5 K
  1015. /* PROCEDURE: Verify                                                                                                        */+ b! M9 m# M5 o5 Q4 t3 a% A
  1016. /*                                                                                                                                                */
    ' j! P. Y1 G$ ]8 X0 _& K9 x% Z% t
  1017. /* This procedure checks to see if the correct byte has be read.                */
      [, O8 v$ S  j6 D4 e0 f; C9 l9 e
  1018. /*                                                                                                                                                */' G3 S( ?. Y) m) m
  1019. /* Input:                                                                                                                                */
    0 K) Z7 W' k2 g1 ~! d$ q7 h: {7 J
  1020. /*                byte:                byte read                                                                                        */% ~9 c0 W2 N$ c9 H$ I
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    ( J' o" t3 F- }& ]* Y
  1022. /*                                                                                                                                                */" h( n* e1 B6 C% L) A
  1023. /* Returns:                                                                                                                                */) _/ f! A& ]: X: t/ N
  1024. /*                Nothing                                                                                                                        */" _+ ~$ L5 V# `* q2 ~$ K
  1025. /************************************************************************/
    % C/ L* |; h1 {8 K' R
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    9 o7 |1 ]8 I; B7 z9 b
  1027. {
    . E. q2 t+ P3 x. n* a
  1028.         if (byte != cor_byte)( d( S# r4 o! V
  1029.         {
    3 U+ D& C4 o0 J3 X% c
  1030.                 while(1)
    8 n4 V3 `* E: _' W. S( O
  1031.                         /* add source code or statement for this file */
    , D) ^  M# y8 N+ t, S9 j
  1032.                         /* to compile                                  */! S7 B+ o) K3 t8 t: G1 E* F; {! s( w
  1033.                         /* i.e. option: insert a display to view error on LED? */, C# v! O1 O1 c( \+ V+ d
  1034.                
    9 a/ J: J% J- p+ o6 z% j
  1035.         }
    5 y* L  L$ l! e4 o
  1036. }
    ! W  @& J( I/ w6 ~8 t1 F+ E3 d7 m

  1037. . h1 t" [5 [' a* b

  1038. 8 i) ~" U: b5 c1 w* a7 K# I8 x
  1039. int main()
    5 H' c: ]/ `8 Z; l, S
  1040. {( ^/ M: _4 a# P  f% ^$ D  T9 C- N
  1041. + H+ R7 a2 q# K$ j- `9 s$ @/ X4 k
  1042. return 0;$ y8 V7 f4 x6 {' D: u# p. \5 ]
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:9 }2 {9 g' Y2 v: @
   main()3 f4 n# Q2 l# R9 `% Q* ^0 Q
   里面怎么是空的呢?
$ V# S) ?1 }- v! r, N   发一份给我吧
) p, k8 G% G7 E3 Z3 I$ i+ j% ?mail:luyijun2005@hotmail.com* m" u  D* z, g# O8 R( ?2 y/ N
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
4 E8 a- g; N) t
8 H8 B0 Z; F0 E$ @2 o# e[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。( i- f4 `" h, B2 @+ U6 n
EC的代码在哪跑,你看DS的说明,每个EC都不同的。' [+ l9 |: q+ x  J" l  }& l
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?( B  D2 l0 L: C2 c
上面几个问题是你没看任何东西而白问。* N; [( \$ e5 G9 q  C
& ^5 `0 C% |9 h, @% v  K
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样$ X1 y' ]/ p: Z. B: F
似乎要把SPI能support 到最大,这EC chip应该有好卖点
  e2 j+ N2 H# K- d5 pBIOS功能要不要强大,也就决定了SPI Flach的大小
9 q8 @; N8 }6 G9 f3 n2 _, |我是这么想的~让OEM去决定要挂多大!
8 H) q4 c! l# Z如果我司有BIOS工程师就好了~哈
6 [& y6 _" U6 @' \4 tWPCE775应该算很新的东西,来看它支持到多大?
, L$ b& ^2 a$ h. o" u. W7 A' B
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
* H* s  }; n) ~- p0 {其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
9 s, [5 d3 c  X& T! H1 B1 F  `9 u1 U) ]2 h+ l; h3 z. c9 t+ F
这份driver收下~希望以后有用到' q3 D$ c* |* O& y2 y) I$ H
谢谢bini大大
6 }* c. ]9 o' m- Z( @+ I
/ e' |, N% X4 n. I2 g很新很新的新手,如有错误请指正 (准备看第二家的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(): U9 ]; P, ~( ?. `
{( x9 n& z) c+ V1 [) G+ [( \
        unsigned char temp = 0;" M9 w5 V. K1 x4 a( r
        CE_Low();
7 J% T9 m" q' f) B2 }, w" m6 s$ K1 j    while (temp == 0x00)        /* waste time until not busy */1 g. |" k- d9 ^$ v8 j* l) g' {
                temp = SO;
# l! [) L* K+ l! O# N        CE_High();6 E- z0 e1 w4 q. v+ e, k' U
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)4 @( ^  w+ m4 t3 n5 m
{
" {8 X6 m  r" T1 W- f        , `3 N- V) A! n. }4 f$ E
        unsigned char i = 0;
- [4 j/ P4 ^1 P# M" L% ]5 I5 D3 K" }$ R        for (i = 0; i < 8; i++)$ f8 I4 R: q( I! g4 v7 y
        {
! k5 V. h) M, \  `1 s* i8 R/ i               
. i9 H7 c2 J  ?                if ((out & 0x80) == 0x80)        /* check if MSB is high */" r" J! @6 |, P; Y
                        SI = 1;* m2 J' S5 l9 h: N/ L3 h$ k; D
                else2 T  _: L7 q; r& @) A; S2 \
                        SI = 0;                                /* if not, set to low */4 d! G8 e% s' T4 G
问              SCK = 1;                                /* toggle clock high */
& W9 D! x9 |/ d0 U/ `3 N+ _   题            out = (out << 1);                /* shift 1 place for next bit */
9 ]6 E+ V, f9 E' |                SCK = 0;                                /* toggle clock low */$ e' Y8 W! O! C6 U$ V2 U
        }/ T* _. f0 S$ t" B* m" u0 M2 a
}
1 ~2 g0 d: ?/ M, K9 d$ M 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-12-1 00:18 , Processed in 0.211714 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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