找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55225|回复: 13

[Software Driver]SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory

[复制链接]
发表于 2007-11-13 11:07:18 | 显示全部楼层 |阅读模式
EC挂接8Mbit SST25VF080B的话,可参考和学习,其它的SPI FLASH雷同。
  1. Software Driver
    ( I# T7 l% O& M, f, _' o/ }
  2. , H- S% ?  \$ L1 ^/ J
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    1 T$ l6 v  o! t# b, y

  4. 3 o' @$ ?) J2 A! c8 _
  5. November 4th, 2005, Rev. 1.0
    : `# o* g/ [7 w1 L% V8 e
  6. ( H, V+ ~" N  e" L0 \
  7. ABOUT THE SOFTWARE
    4 \2 T. S. c. H
  8. This application note provides software driver examples for SST25VF080B,$ c% ?1 z6 W" ^- d# g- K- w9 [: a
  9. Serial Flash. Extensive comments are included in each routine to describe * V7 c. V: W- ^
  10. the function of each routine.  The interface coding uses polling method
    ; e- }; V9 _! j1 {% }+ N0 L
  11. rather than the SPI protocol to interface with these serial devices.  The" c# R; |% N5 y/ p/ u+ {
  12. functions are differentiated below in terms of the communication protocols7 r* z/ B8 ~" t+ `
  13. (uses Mode 0) and specific device operation instructions. This code has been 8 I. i& h6 z3 f2 e8 A& L
  14. designed to compile using the Keil compiler.
    9 _4 q* {7 w- T7 q

  15. * j- e; g4 O! k

  16. & N; R- e1 l. W# X: X
  17. ABOUT THE SST25VF080B
    4 R: y* l( [6 `
  18. ! f2 l5 ~  |4 s: t/ C
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    ! M2 T. V+ V6 T3 r* W( U8 F7 R" h
  20. conjunction with this application note for a complete understanding   @& d% p4 z  P: a1 d: f
  21. of the device.4 J; E$ B: P5 x; y1 @

  22. / f3 S' d  z5 ~0 W8 }. F

  23. ! j: `. s+ Z3 \" b
  24. Device Communication Protocol(pinout related) functions:
    ; F, t: b! E$ `4 P
  25. 2 r6 Z( Z# T2 F1 ~; w+ p
  26. Functions                                    Function: n' _, c- R/ O/ P$ d) I6 R8 `
  27. ------------------------------------------------------------------2 y( ~% I5 L6 O( w& b
  28. init                                        Initializes clock to set up mode 0.
    % C' g( s0 C/ d  i
  29. Send_Byte                                Sends one byte using SI pin to send and
    5 v/ n/ m/ r2 o2 `
  30.                                                 shift out 1-bit per clock rising edge6 t1 j6 }3 C! a4 C5 J" ?
  31. Get_Byte                                Receives one byte using SO pin to receive and shift 5 S# `7 P  f5 |, _' u
  32.                                                 in 1-bit per clock falling edge
    / K. K- _, j; ]/ B6 R+ B
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    $ m+ j4 y% \6 i- ?  D3 q
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high; n. j& e5 _4 ?0 W% ]
  35. CE_Low                                        Clears Chip Enable of the serial flash to low: H3 o# ?) A$ K" c+ u" O
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    4 T6 o+ F4 {$ V3 @+ s1 v* m
  37. Unhold                                        Unholds the serial flash
    " F5 V  C5 n' A( ~: z
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    ; i5 e; q# B. \, S4 m( k: U
  39. UnWP                                        Disables write protection pin7 o% `: K2 P& U+ G) C

  40. : r+ C1 L  I6 h, ~  T  w/ L1 r
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code, @; B2 S$ v1 x9 r5 w% O
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    ! @+ y% s* i  d5 U8 r+ X% r
  43. software which should reflect your hardware interfaced.          ( e1 H: {8 N( Q. u  h6 f$ @1 ~9 l# R* E

  44.   R8 {. }6 {' v1 ^: d; g% c
  45. 8 t% }. P6 I; h6 o, z7 m
  46. Device Operation Instruction functions:
      K% Q4 r) I7 A
  47. 3 i2 ?" g# }$ Z5 j! [+ ^0 K: E$ u
  48. Functions                                    Function
    ) w6 ]. M/ i4 `+ q; s3 @, B) |# W6 V
  49. ------------------------------------------------------------------. {9 P) A! O. ~
  50. Read_Status_Register        Reads the status register of the serial flash
    3 A; Z' I% o# p8 i
  51. EWSR                                        Enables the Write Status Register6 d2 W3 m: H6 [5 b
  52. WRSR                                        Performs a write to the status register+ q1 G* J% w% x# z. k+ d
  53. WREN                                        Write enables the serial flash+ g5 u, x2 o, g4 u" I3 u: |5 E
  54. WRDI                                        Write disables the serial flash
    % V+ s  Q; D* M
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    # T3 v$ H, g3 c# e7 W; F
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    7 |. ]8 B2 e9 N: b# Y% @* {
  57. Read_ID                                        Reads the manufacturer ID and device ID
    9 `& h. i: @) N& k! t5 M
  58. Jedec_ID_Read                        Reads the Jedec ID. \; P7 q+ |+ r! l
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)" U  ^2 }6 B7 y/ B: ?* m' {) i
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    ' `6 a. L5 }9 z7 h/ ~8 z8 `
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    2 j# W+ h0 ]2 n! \+ _
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)1 S: ^" Y% I# {3 h0 }
  63. Byte_Program                        Program one byte to the serial flash
    ! s5 o7 |; c) p9 g% }$ {
  64. Auto_Add_IncA                        Initial Auto Address Increment process# Q9 ~0 P* U2 ?0 _/ \" [! p
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation! h, U- G1 y/ ]4 o6 Y" j
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    5 M/ \/ G: o: a' u, k
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY. d9 Y0 q) V& f+ @" r. E
  68. Chip_Erase                                Erases entire serial flash
    8 X# [" C, F9 }: B
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash5 c) T! j( K& y  a+ v
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash, j& Z/ E* A2 ~7 {
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    1 M3 i1 S4 Y" H9 C# ~& H
  72. Wait_Busy                                Polls status register until busy bit is low
    8 N3 D! m: n- H; d
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming# `' h, o& e* G8 \
  74. WREN_Check                                Checks to see if WEL is set
    $ F7 r) ]; R/ U& M! S3 p
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    ( S6 G6 G; P. f* m! m
  76. 8 t7 R4 w/ [& {! V3 M

  77. ! |* @6 V1 T3 C# b

  78. ' Q8 c9 v% S. ]( @9 Y5 b6 b: }: F
  79.                                                                      5 V0 K( ]- t" G2 L) b% S% s9 h
  80. "C" LANGUAGE DRIVERS . X: @( c2 Z, R7 m# ^# r6 ^

  81. , v# ~* q$ w% h/ P& q
  82. /********************************************************************/' q/ A9 t, n' \: t" K) N$ a% c
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    + E9 y" V0 N5 l
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */# ^% p: S. |, q# v' H
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */+ q6 ^1 z/ d8 I8 F: E2 F
  86. /*                                                                  */
    ' z9 I5 T! B, G1 J
  87. /* Revision 1.0, November 4th, 2005                                                                          */   3 o1 S) I) o) w. {
  88. /*                                                                  *// E$ C% K8 j7 Q+ }3 S
  89. /*                                                                                                                                        */
    ' ?1 @5 X9 X" n0 y& ]* r
  90. /********************************************************************/
    % G3 n. u& y; Z3 |, `' A
  91. , v# f7 U) L: g% a/ b3 E
  92. #include <stdio.h>
    8 k5 ?' O# g, B4 U: x
  93. #include <stdlib.h># y9 X( R/ V6 I- T

  94. ( h( l6 n% u1 U7 j7 _' O
  95. /* Function Prototypes */
    * l1 z/ h4 d' B
  96. ( G4 n" y: v+ X* r" z3 X
  97. void init();
    4 t; m* z) y2 T5 J) j
  98. void Send_Byte(unsigned char out);
    - d* y: G4 q3 K7 b4 E
  99. unsigned char Get_Byte();2 i$ |' C! |$ x  O
  100. void Poll_SO();
    , S/ c) s6 K8 Q: ]7 K
  101. void CE_High();6 r* @; Y" c. N% M. Q5 D% @' y, E( f
  102. void CE_Low();! |6 |  J  R) P, w' |
  103. void Hold_Low();
    ) ?' `+ O# T: J) K' ?" X) C1 v
  104. void Unhold();* ^9 W: o$ }% [8 b" ]
  105. void WP_Low();) X( W4 V0 U" I: R
  106. void UnWP();: s- q/ ?0 c- k8 B) ~2 ]
  107. unsigned char Read_Status_Register();
    6 v9 m1 X9 d0 |- T. z, B) [
  108. void EWSR();
    0 x! w% j( o7 C4 ~/ S/ V- A
  109. void WRSR(byte);6 Q2 N! _3 r4 n) ]
  110. void WREN();
    , C1 A5 C/ y3 T. J
  111. void WRDI();* x+ M/ Y) L6 u6 {/ q9 ?, O
  112. void EBSY();1 o1 z1 E5 y! N8 s4 x& J
  113. void DBSY();8 p: u# ~) y+ s, i5 [
  114. unsigned char Read_ID(ID_addr);2 v% @7 Z7 D7 Z: K
  115. unsigned long Jedec_ID_Read(); , Q  q5 p0 b3 H
  116. unsigned char Read(unsigned long Dst);  S9 ^$ W+ w# A, g- M' K" }5 M
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    % ~9 D" k$ e8 Y0 `8 y
  118. unsigned char HighSpeed_Read(unsigned long Dst); 4 u% Z9 Q% B4 w) D- |
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);9 P0 _$ n( F% `
  120. void Byte_Program(unsigned long Dst, unsigned char byte);" A& V, N8 [- c; c
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    + A: G/ z! i/ C; ]
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);# ~% T7 L+ J2 _2 G
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    . a2 j# s7 o% G3 Y' i: ~+ w* s
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);0 J0 i. z- w; q3 U1 J
  125. void Chip_Erase();' F, s8 a0 V6 p8 `
  126. void Sector_Erase(unsigned long Dst);
    6 N2 X( s* R* g  a
  127. void Block_Erase_32K(unsigned long Dst);5 K5 ~' x0 `7 S& R# t+ q! ?3 h
  128. void Block_Erase_64K(unsigned long Dst);- ]+ K5 j) w1 \- \5 w7 R
  129. void Wait_Busy();8 P  O: f4 O: t4 W5 o* ^
  130. void Wait_Busy_AAI();8 ]' i% ]% Q4 J% R; E
  131. void WREN_Check();/ e& W- t% {: W, Y+ J6 u6 X
  132. void WREN_AAI_Check();: N7 C) y- T! V8 g

  133. $ R7 l/ G. x; L& N% @
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    ! w) `9 s6 q) y. t
  135.   M* ~) }" q7 R7 ]& }( ?" e
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    4 u/ T# C, `! @* o+ }
  137.                                                                                 /* to upper RAM area from 80H - FFH */: d1 D4 l: y/ V0 Z  s- n2 N

  138. : Q# }& D3 v1 _  e; f+ s
  139. /************************************************************************/& I! l1 A7 v, d( ^
  140. /* PROCEDURE: init                                                                                                                *// D1 |3 E3 t/ j+ f, E4 Z
  141. /*                                                                                                                                                */
    * D9 K& T. W9 Z! v7 F. t4 l
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    " Z( S5 d/ x. x5 _4 D
  143. /* setting up mode 0.                                                                                                        */
    . K# z# a) \* U( c
  144. /*                                                                                                                                                */9 h+ \1 y  Q/ |$ t
  145. /* Input:                                                                                                                                */. C& G) K/ R, a7 {
  146. /*                None                                                                                                                        */- }1 p" Y2 i* N/ X4 m0 U! t: M  i
  147. /*                                                                                                                                                */
    9 ?+ D- w2 Z( t( B1 _
  148. /* Output:                                                                                                                                */
    # U; C2 z: T1 Y& J  {: z
  149. /*                SCK                                                                                                                                */3 g# w3 c# S$ u$ E
  150. /************************************************************************/
    , a+ z6 i( w( U% ~( S" H3 M' j
  151. void init()
    % B% C* ~" b* c+ H
  152. {
    " t: k9 r, ]& q2 h0 C  B
  153.         SCK = 0;        /* set clock to low initial state */
      y! ^4 P, K6 ]4 M( F  Y9 T
  154. }
    7 ?# q5 Y6 P  s/ ^  f5 i  b
  155. 2 l. j$ [* M- o  l- r4 G0 i9 r& w
  156. /************************************************************************/
    3 l/ ^4 E- l8 l/ }  I8 |% T1 L
  157. /* PROCEDURE: Send_Byte                                                                                                        */
      h9 L/ l7 Z1 u! X% h
  158. /*                                                                                                                                                */
    * I4 {' Z, t: X$ t5 [: L
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    ; ]: K7 v% X/ T+ \
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    + c5 H6 `' Z- e: B# ~7 I
  161. /*                                                                                                                                                */: `5 \' |- v- S/ Z7 H$ m+ G9 y" F0 S
  162. /* Input:                                                                                                                                */9 J# ?% a# }2 q6 F( }- V; l
  163. /*                out                                                                                                                                */
    - [) B6 |9 \- f- s2 v
  164. /*                                                                                                                                                */
    , J' Q3 [( a8 B9 d0 k1 G: C
  165. /* Output:                                                                                                                                */
    * @- N1 [* q5 m& J- M; P. N1 @. c
  166. /*                SI                                                                                                                                */
    + E, y  W( d& s7 f& x
  167. /************************************************************************/9 N5 j4 ]4 Q, i$ c+ v' I  L9 E9 I
  168. void Send_Byte(unsigned char out)
    ( `) q: T8 B2 O' t& k8 ^5 r& f! S
  169. {' I$ F) o6 ~9 N2 R6 _, p* B3 V: @" k* j
  170.        
    3 |# K$ q/ l8 s+ e3 o3 p& N9 M
  171.         unsigned char i = 0;; V; a) T* V$ q" J$ t
  172.         for (i = 0; i < 8; i++)0 F9 U% W3 ~% l$ O! b8 ]
  173.         {
    7 }' f8 I! m* g' g- |! R
  174.                 " F" x0 V, P8 D% C
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */0 X' p( t9 Y/ V& r+ G
  176.                         SI = 1;
    5 o, F) H% k: d) t4 O% m& p/ x! {
  177.                 else
    0 O  F& s$ A, o
  178.                         SI = 0;                                /* if not, set to low */
    9 K7 ~* t& @: h0 J
  179.                 SCK = 1;                                /* toggle clock high */
    , d: X! _( r  m( D  @
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    : \1 J! N; d2 H% {8 [( p
  181.                 SCK = 0;                                /* toggle clock low */8 I: S) j. p' K) V. }" y! i' n
  182.         }# ~" _4 J" E( L
  183. }+ V2 {4 D; M; X  L4 w, }1 A0 d

  184. , K3 w5 ~5 u/ g' M" w% j; H: r
  185. /************************************************************************/
    # E" a# R1 `+ v* d& f0 J8 ]8 q7 j
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    ; H7 d$ r+ T( o0 t$ J4 T
  187. /*                                                                                                                                                */# r$ O5 I  ^. Q% c& w
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                *// F8 n( u4 I5 h, |1 i* t
  189. /* edge on the SO pin(LSB 1st).                                                                                        */+ f9 B% m8 J* t# v
  190. /*                                                                                                                                                */
    : q2 t) |$ o6 y, i1 h
  191. /* Input:                                                                                                                                */& |0 X% o. n- C: ~  t
  192. /*                SO                                                                                                                                */
    8 b% e8 K1 Z# ]8 F: b" ^% f. }
  193. /*                                                                                                                                                */
    - `3 t" z1 b9 \6 l$ g! W
  194. /* Output:                                                                                                                                */
    ( f  L) E* W8 m3 w- K
  195. /*                None                                                                                                                        */
    ' H$ P$ t  J) @, n; t8 v( I
  196. /************************************************************************/
    1 C) Q3 D$ |, b  V7 e1 V
  197. unsigned char Get_Byte()
    : k- X9 Z* n' C: C, D
  198. {2 v5 S  \, ~; d& T* g
  199.         unsigned char i = 0, in = 0, temp = 0;
    7 I5 D) k. s6 G6 ~8 d2 A  P& |" ~  y
  200.         for (i = 0; i < 8; i++)4 ^. S" A* u% E/ H0 P
  201.         {
    $ T' g6 y% V6 H+ m
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */5 k! u; E- D3 [& u
  203.                 temp = SO;                        /* save input */7 j2 v' o; l' b. a- m8 \  M) X
  204.                 SCK = 1;                        /* toggle clock high */# x- ?% y% x  ^) u* X+ @
  205.                 if (temp == 1)                        /* check to see if bit is high */
    8 G* {5 y: V, x4 f, M7 d( K, x
  206.                         in = in | 0x01;                /* if high, make bit high */7 i2 A+ z: e5 O. u* Y
  207. 3 e0 ]6 z, |1 ~; V! z- k
  208.                 SCK = 0;                        /* toggle clock low */$ S' Z2 M) N5 T5 X) ?+ D# p  @

  209. : g' c  f9 w) D
  210.         }
    5 V8 e& T6 q- w. x) ^9 Y
  211.         return in;
    : ^% M+ R' U7 P# k1 L
  212. }
    * B* R3 P6 G7 y. u( y8 t# N
  213. ' {: Y) L- @9 E+ \; J
  214. /************************************************************************/$ B  K" G; H  b- B2 k
  215. /* PROCEDURE: Poll_SO                                                                                                        */8 a( s9 T) g6 d
  216. /*                                                                                                                                                */
    * A; ^3 s2 i1 @7 t5 ^
  217. /* This procedure polls for the SO line during AAI programming                  */' U' o( r/ o* D4 G. ^" p
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    ' K, B# _/ c% r
  219. /* is completed                                                                                                                        */
    4 L* u8 c" o/ `$ Q  H/ X1 }
  220. /*                                                                                                                                                */5 ^- S. c9 D5 g$ C, K
  221. /* Input:                                                                                                                                */* @7 @: G5 F6 h3 ^+ W% Q  a
  222. /*                SO                                                                                                                                */, x0 @* E# l3 ]( F% X- ^
  223. /*                                                                                                                                                */# T3 K8 T- U1 x7 d
  224. /* Output:                                                                                                                                */
    7 r/ h  _% S, k$ }3 Z' T/ ?
  225. /*                None                                                                                                                        */
    6 `, B2 c7 t7 q  L) ]" ?
  226. /************************************************************************/
    % h! u3 }% @- \  i: e- X( `
  227. void Poll_SO()
    4 l, y  T9 C. Q/ I$ m
  228. {5 E' x8 T% b3 _& t: q, q
  229.         unsigned char temp = 0;
    3 ?9 |$ Z" o/ g6 c' i9 u4 i
  230.         CE_Low();
    $ p: I% ^5 U$ Y' n
  231.     while (temp == 0x00)        /* waste time until not busy */
    " A) ^  o" [) m0 d& Y4 W& r/ i
  232.                 temp = SO;! J3 ^5 [' U) a2 v3 j
  233.         CE_High();) H- C1 c/ d/ m9 P% v$ V  w  S
  234. }
    ' p. T9 C# s$ J6 h# H- D+ Q9 s

  235. / \0 |) G% K# q. l( c* v
  236. /************************************************************************/
    ( `/ m1 @8 M& {" E. M( K( |
  237. /* PROCEDURE: CE_High                                                                                                        */' e" |$ E. O  i+ g% d
  238. /*                                                                                                                                                */; i+ s$ Q" ?  S4 R6 u  ]
  239. /* This procedure set CE = High.                                                                                */# [! T9 u" G) T  Y5 E0 Y
  240. /*                                                                                                                                                */4 G/ a2 |0 d7 g, f- Q0 V
  241. /* Input:                                                                                                                                */
    7 A) ?. h4 @9 ^6 Q6 X
  242. /*                None                                                                                                                        */5 q$ j) p6 w: I& |/ a) b& U$ @
  243. /*                                                                                                                                                */
    6 L& I  E. T) c$ I5 q. f
  244. /* Output:                                                                                                                                */* ~6 Z9 S9 d0 f+ o7 D
  245. /*                CE                                                                                                                                */
    5 ^& C' E1 J3 L. }$ D5 C
  246. /*                                                                                                                                                */. ?1 \* e4 H+ i% l) M2 `
  247. /************************************************************************/
    ) y7 N- ]8 Z' [" z7 t6 V1 A
  248. void CE_High() % u8 C& }/ @/ {' {4 b3 F4 s
  249. {
    # K% W9 V9 X( {4 h' u% p
  250.         CE = 1;                                /* set CE high */; D; ~5 g& G, O* ~7 z, g
  251. }
      G7 Q+ m" u. @1 \1 A& t
  252. 0 k3 ~; j" G$ I( [8 k
  253. /************************************************************************/
    9 E4 Z  ^) q3 i3 D, v7 P  X/ Z
  254. /* PROCEDURE: CE_Low                                                                                                        */4 X4 q! O" c: J. a# ?# M
  255. /*                                                                                                                                                */* p4 S8 U& x/ I8 r8 K" L: V* u
  256. /* This procedure drives the CE of the device to low.                                          */' M) `  v- e* g9 \& Z8 s; z
  257. /*                                                                                                                                                */
    5 s4 ~$ `6 m; Z/ ]: ^, s
  258. /* Input:                                                                                                                                */
    , n2 Q$ f% N9 [
  259. /*                None                                                                                                                        */) E/ x2 m/ f6 [$ W3 b% I+ }" F
  260. /*                                                                                                                                                */$ x% M5 b5 l- w7 \
  261. /* Output:                                                                                                                                */! n1 H) r  n2 L4 q6 U5 z* B
  262. /*                CE                                                                                                                                */" ^" m- u. R; T& X
  263. /*                                                                                                                                                */
    & S2 e" C  m& y6 m! v
  264. /************************************************************************/
    7 ^) o0 ?: y* i! O7 ]6 \
  265. void CE_Low()
    ; [+ u" e% W7 J# U5 x! s+ m+ y. y: c$ ~% U
  266. {        3 F7 `. T7 N( V  o, q
  267.         CE = 0;                                /* clear CE low */
    1 U& v$ {5 u6 ?, f
  268. }
    0 f; v7 E! F0 s! P9 u3 d. s  ]
  269. 9 e1 r" o* c$ S2 u; ~: F) o% B4 X/ T
  270. /************************************************************************/
    ; s5 L* O7 `4 S
  271. /* PROCEDURE: Hold()                                                                                                        */# O0 `+ w% Q/ A. r/ C# b
  272. /*                                                                                                                                                */
    % o) e5 F; B) M4 }2 X% `7 |
  273. /* This procedure clears the Hold pin to low.                                                        */7 }4 V, D3 r/ ~8 l
  274. /*                                                                                                                                                */) s: S9 E; E0 K3 N
  275. /* Input:                                                                                                                                */3 \) E8 P% m! X8 f+ H0 q
  276. /*                None                                                                                                                        */
    ( g) j3 Y8 G/ o
  277. /*                                                                                                                                                */
      ~/ l# `9 a/ A# @) V( L
  278. /* Output:                                                                                                                                */6 H, w7 F% `; N; u+ j
  279. /*                Hold                                                                                                                        */; v9 @, G- G$ F  D1 f6 X# ~
  280. /************************************************************************/
    . J2 j3 V/ b% Y; H+ |: b' A
  281. void Hold_Low(): W% c' }  d# V; y9 ]9 j# z  L
  282. {4 R9 E5 F1 T8 j
  283.         Hold = 0;                        /* clear Hold pin */
    % s9 V6 \! O  ]9 J  m/ U9 s. e9 U
  284. }
    % P; [9 ?: p* n  k/ O9 T0 Y4 I

  285. 1 M* l3 o, ?6 d! l' k$ H7 N* i% ^1 E" i
  286. /************************************************************************/+ o, s" G$ g" U: w5 C' A
  287. /* PROCEDURE: Unhold()                                                                                                        */# `) ?% m. i4 L
  288. /*                                                                                                                                                */: q8 b# F$ W0 H2 m$ y: J
  289. /* This procedure sets the Hold pin to high.                                                        */3 `8 [$ m  h) U5 T* ~* n) R2 n% e2 y
  290. /*                                                                                                                                                */
    3 ]2 `* E. C; c5 Z( j1 H; V
  291. /* Input:                                                                                                                                */3 ?/ a" n/ H- `( u" F
  292. /*                None                                                                                                                        */8 P5 N! e8 t3 T) n
  293. /*                                                                                                                                                */$ `3 x2 k  o* j: p, P* M
  294. /* Output:                                                                                                                                */3 c- e* U" V/ I" R% F( W& L2 M% E4 D$ ~
  295. /*                Hold                                                                                                                        */
    + ]1 d/ ~0 |5 \3 x5 q' U
  296. /************************************************************************/
    % \! c7 W- Y7 h$ w6 u5 g
  297. void Unhold()' y9 y* c8 e2 K
  298. {1 Q( C. q; R; S) k+ Y' e5 R% t
  299.         Hold = 1;                        /* set Hold pin */
    , m* X7 I% ~& f6 q2 G
  300. }$ K# W* K4 g5 g+ J% s6 P, B& G
  301. 8 ^) D# h# B- J7 i% l0 V5 v
  302. /************************************************************************/
    6 J$ p$ U7 t# \$ K" v
  303. /* PROCEDURE: WP()                                                                                                                */
    # _5 A; ]. I6 a; O" d+ b
  304. /*                                                                                                                                                */$ M9 N4 e; q- V' A0 w' u
  305. /* This procedure clears the WP pin to low.                                                                */
    ! D) j% W9 C1 M+ E. y
  306. /*                                                                                                                                                */
    ' o: N. w' o7 U7 d7 A2 Y2 t' L
  307. /* Input:                                                                                                                                */
    1 K" A4 K/ R+ ]; r8 C& a
  308. /*                None                                                                                                                        */
    / \2 E. v6 e, \9 k& K5 u! t' F
  309. /*                                                                                                                                                */( l( |/ n& W7 w( y
  310. /* Output:                                                                                                                                */) S# v- @: X7 h8 A4 h/ [% {7 M
  311. /*                WP                                                                                                                                */
      P8 \8 d; {' J# S
  312. /************************************************************************/) J4 `3 L$ d  x- j- J) |& Z
  313. void WP_Low()7 [% s' J/ L( J* Z4 A6 W- @
  314. {! j3 G6 E. K. K
  315.         WP = 0;                                /* clear WP pin */
    ( s3 |9 T4 a- x( |' G- [
  316. }
    , b( I! X: U6 c$ W

  317. - q' m3 }+ `( C7 R: c6 W" P8 t- K
  318. /************************************************************************/: }: J3 @- t/ u  w$ Q
  319. /* PROCEDURE: UnWP()                                                                                                        */6 }2 @9 m/ ]* x$ Q  T7 X9 l! @
  320. /*                                                                                                                                                */
    8 [) S8 M$ e! j+ t' I$ Q9 C+ N
  321. /* This procedure sets the WP pin to high.                                                                */( z% I7 t! X+ @, n3 S
  322. /*                                                                                                                                                */+ P1 b# {/ A  _  e  ~# L- u% Y
  323. /* Input:                                                                                                                                */- [( [7 S# D! S/ K8 x0 w
  324. /*                None                                                                                                                        */
    ' i* Y- {- H/ E
  325. /*                                                                                                                                                */5 D' Z  c3 G3 f* n4 [
  326. /* Output:                                                                                                                                */5 B9 s& e- M% T9 u
  327. /*                WP                                                                                                                                */) `' \  F: _3 ]
  328. /************************************************************************/& u+ Z! G; P( t1 e3 O* ]
  329. void UnWP(), Y8 v- O0 o% C, Z" ~$ u* E
  330. {# s  Q9 @& k) N1 K; F
  331.         WP = 1;                                /* set WP pin */
    $ X* \; c2 p1 z
  332. }
    4 B7 k/ J5 `- {9 U' ]

  333. 2 x1 l: \) x. j2 a( R* p
  334. /************************************************************************/
    7 R, h5 B% Z/ {' y# ~
  335. /* PROCEDURE: Read_Status_Register                                                                                */7 A9 e3 g1 z0 l: M  S1 v
  336. /*                                                                                                                                                */
    ' t+ ^+ t6 ], j
  337. /* This procedure read the status register and returns the byte.                */
    7 H* v  i4 r) o7 a2 c% P
  338. /*                                                                                                                                                */
    4 T# G3 ~& V% |
  339. /* Input:                                                                                                                                */
    & h/ h- d% N. a  E
  340. /*                None                                                                                                                        */( @! |& C+ |. O2 k) |/ Q9 T
  341. /*                                                                                                                                                */$ c: ?; i' S# u
  342. /* Returns:                                                                                                                                */
    9 y2 z3 B7 x: w; t7 j
  343. /*                byte                                                                                                                        */
    9 m' ^9 A6 }8 ]8 V& J
  344. /************************************************************************/2 ~' w* ~6 R. w9 T! g; ]; s4 ~
  345. unsigned char Read_Status_Register()9 K% T% Z8 C; n4 M3 D
  346. {
    0 n3 y! X3 I3 m: V, A
  347.         unsigned char byte = 0;
    4 v) ?3 W' V6 n9 x
  348.         CE_Low();                                /* enable device */  v' q, b5 L0 }1 {" {' R
  349.         Send_Byte(0x05);                /* send RDSR command */
    ) s* b0 N1 l" g# m/ i/ ^
  350.         byte = Get_Byte();                /* receive byte */$ {; q1 y; o. k
  351.         CE_High();                                /* disable device */* c* m; c* u7 K9 i/ T1 s! G* j
  352.         return byte;
    5 d8 y! J0 G- ~
  353. }4 h2 I3 F' w- {3 ]- d. _5 D# x
  354. : b& Y/ p+ D% v/ g$ p9 v
  355. /************************************************************************/9 p" T3 ?* ?. i: _' s- Z
  356. /* PROCEDURE: EWSR                                                                                                                */
    - x! I; I" G& V8 e# m& z0 c" Z7 F
  357. /*                                                                                                                                                */( e2 G1 x( h0 s
  358. /* This procedure Enables Write Status Register.                                                  */* O: A) `+ G+ E1 T) N+ H
  359. /*                                                                                                                                                */
    5 Y) b/ v, I2 l9 R1 U
  360. /* Input:                                                                                                                                */
    % P( ]/ Y# U& f0 M& @+ [  q0 y7 }
  361. /*                None                                                                                                                        */% D3 F3 d7 \: z! z- q% p& ~
  362. /*                                                                                                                                                */* W2 a  E4 d- A! l
  363. /* Returns:                                                                                                                                */
    ; R% N& c  Q( h/ @" @
  364. /*                Nothing                                                                                                                        */. K7 z, t$ G+ E& }$ t) h
  365. /************************************************************************/
    & M) G5 @; x  L
  366. void EWSR()4 K- a0 ~- D2 e" C, n# n) Y) v0 T
  367. {( {6 N+ f3 [: s5 O' j
  368.         CE_Low();                                /* enable device */
    ! U* T! N- u5 x( y8 [
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    & g- d, @3 b' [+ _
  370.         CE_High();                                /* disable device */# |  [5 y. {" p
  371. }. N6 `; I% H' Z+ m( z
  372. 9 a4 I5 Y; U% {9 ^' X8 H1 f
  373. /************************************************************************/
    ) r# E' t7 P, C2 Z8 g  b0 q: J+ J
  374. /* PROCEDURE: WRSR                                                                                                                */5 ~& K2 t2 ?: C9 d" s9 e; s
  375. /*                                                                                                                                                */
    7 r) m* i: O  W; V
  376. /* This procedure writes a byte to the Status Register.                                        */+ b; U( m8 i9 `
  377. /*                                                                                                                                                */; O4 I3 F4 `+ b2 d( X/ ~
  378. /* Input:                                                                                                                                *// _: d) k$ W7 B  e( s
  379. /*                byte                                                                                                                        */
      E8 @! s2 R9 D0 u. O7 o
  380. /*                                                                                                                                                */
    % [! U" G$ |& S4 C) O
  381. /* Returns:                                                                                                                                */4 O8 \' R9 ]( j
  382. /*                Nothing                                                                                                                        */
    + b4 E  {7 j5 f
  383. /************************************************************************/* }; ]4 p2 g, u
  384. void WRSR(byte)& C' y* V3 b+ W3 w5 W6 s& M8 g' j2 `6 K
  385. {2 H) f* }# p: O  {+ Y. K# y4 M) e
  386.         CE_Low();                                /* enable device */# T) k" L3 |9 D
  387.         Send_Byte(0x01);                /* select write to status register */8 J2 S$ ?" S3 s4 i; D# r% P
  388.         Send_Byte(byte);                /* data that will change the status of BPx & s0 v5 c0 Q2 l1 w* s  M" D8 F
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */" D+ {! q+ w0 a: x- x: d
  390.         CE_High();                                /* disable the device */: P% B' A5 {$ x3 I4 r# O! e8 X
  391. }
    # C* l& y0 D2 v6 ^" ]  H# p

  392. ; X% w  A6 E# t. h( k* ]# a/ C2 W
  393. /************************************************************************/
    " v- V; V$ Z( t7 c. S- L  D
  394. /* PROCEDURE: WREN                                                                                                                */9 |* q, H3 L! B/ o  M! N3 O1 G2 l& }
  395. /*                                                                                                                                                */
    7 ]8 \3 }5 D  K" n7 O- B
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    3 o) ^2 G$ z4 S6 i1 I
  397. /* to Enables Write Status Register.                                                                        *// X7 O% K5 V0 X" x
  398. /*                                                                                                                                                */
    6 d0 x' v4 l% o9 r7 x. ]8 G! N" Y" O
  399. /* Input:                                                                                                                                */4 J5 D& c" T2 r* ]" i
  400. /*                None                                                                                                                        */; \+ S( o+ s" B2 J6 h
  401. /*                                                                                                                                                */
    . [/ ~! e9 ^! t6 p
  402. /* Returns:                                                                                                                                */7 m, F. k% V: e" {/ Y! v: |6 t3 f$ ^
  403. /*                Nothing                                                                                                                        */# Q% x) Q* c6 N. C1 T5 C" Z8 k
  404. /************************************************************************/' }3 X1 o# A5 s. H( L( n7 w2 {- H9 [  x
  405. void WREN()8 M, L0 g# L. F! j. ]: S0 M
  406. {) `3 j! y" j$ U, s/ O* m3 `
  407.         CE_Low();                                /* enable device */( m* o- ]! U& h
  408.         Send_Byte(0x06);                /* send WREN command */) S- x/ F% G$ P9 u9 D
  409.         CE_High();                                /* disable device */
    . Z: U7 G* N- q8 T; [, h) B9 i# e: Q
  410. }
    % u. [5 }/ N- i+ _  u, O: s& {

  411. & ~" r9 b' O! o: ]
  412. /************************************************************************/
    & Z2 l( O8 P; ?" i. e& d
  413. /* PROCEDURE: WRDI                                                                                                                */& D* E" P/ ~7 f9 j- b! m! J
  414. /*                                                                                                                                                */6 v0 w' n8 Y/ ^* d, e4 D
  415. /* This procedure disables the Write Enable Latch.                                                */. C, S% N' Y3 S! H& X
  416. /*                                                                                                                                                */
    4 R! m( F) b+ k9 F" M$ E% g+ Z  m
  417. /* Input:                                                                                                                                */5 p4 L% q1 u2 A2 c" @- n- i
  418. /*                None                                                                                                                        */  ?# h) _1 q( Q$ n. }
  419. /*                                                                                                                                                */( N( z8 t+ ]9 h* Y
  420. /* Returns:                                                                                                                                */
    1 s' K5 ~; J$ N5 t- V  \5 h+ A6 R
  421. /*                Nothing                                                                                                                        */+ U4 T. t$ _# V$ r( w  j
  422. /************************************************************************/# E* }- Z& y' F, R3 d4 Q
  423. void WRDI()2 C  U# L' T, m# R5 F
  424. {
    & |& M3 I6 Z/ Q& {& c
  425.         CE_Low();                                /* enable device */; u5 e* f! a& ~9 p
  426.         Send_Byte(0x04);                /* send WRDI command */
    4 M/ Z3 M+ ^( ]  G& Q; Z" K. G5 S9 z
  427.         CE_High();                                /* disable device */
    & R3 T4 d8 W! L8 |* x
  428. }
    $ m5 x. z1 j% x2 ~! z
  429. & o% w/ b( m/ y! j7 g# T
  430. /************************************************************************/; _' t5 V  e4 u: w# a( z8 [: {1 o2 t
  431. /* PROCEDURE: EBSY                                                                                                                */8 q  I/ d! K9 F1 T7 }
  432. /*                                                                                                                                                */
    ; |8 N1 W# r" H4 c5 B! V
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */. E+ z9 }8 U, y2 \, A! D
  434. /* programming.                                                                                                                        */, _% S: a* b; d, ~, y% V2 ?
  435. /*                                                                                                                                                */
    ' T# O* O; U0 Z8 v3 |! Q
  436. /* Input:                                                                                                                                */
    1 A" g0 v# U/ z7 X( M" q% U
  437. /*                None                                                                                                                        */
    $ q2 W/ T9 X! w
  438. /*                                                                                                                                                */! x. g( Y8 H: j  K
  439. /* Returns:                                                                                                                                */2 I  J. \5 c: ]' j
  440. /*                Nothing                                                                                                                        */  V0 T* b- Y- l! b# r" R' M
  441. /************************************************************************/
    - D( m! C2 s( E6 ^% }  O; i
  442. void EBSY()
    7 C  }8 y) o# v" m0 O
  443. {8 k! @) P0 V  E1 Q) A7 o* `
  444.         CE_Low();                                /* enable device */
    . c, V; n) ]! V0 V# r
  445.         Send_Byte(0x70);                /* send EBSY command */
    ( Z9 ]0 J! _5 z7 y; D3 O/ a( Y7 I, F
  446.         CE_High();                                /* disable device */
    % b  [3 Y& U8 T  A
  447. }( I# u# I7 {- N/ p* x3 {7 v0 H( w
  448. 3 K. y* _9 ^* K
  449. /************************************************************************/8 U% Z3 I  N" T" p1 c% |6 j
  450. /* PROCEDURE: DBSY                                                                                                                */
    ! z9 G5 M% H' F7 ~
  451. /*                                                                                                                                                */
    5 ?: r$ a0 |, i
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    # w+ T) l0 V  P/ l: Y, g
  453. /* programming.                                                                                                                        */  q% ?) q5 s& }* w
  454. /*                                                                                                                                                */
    5 h9 w7 C1 v+ o: N$ u) A* Y& E
  455. /* Input:                                                                                                                                */
    $ K1 a5 ~2 l. D; x6 V3 g* |, g  `% L
  456. /*                None                                                                                                                        */
    : [4 L  C. T4 m, Y$ o) r3 f
  457. /*                                                                                                                                                */
    ( i2 u$ Z7 O; c, l* `
  458. /* Returns:                                                                                                                                */) f9 [3 P- Z; ~) k. u- n& W2 K
  459. /*                Nothing                                                                                                                        */
    ' q, c' m' l. ^4 @! ]
  460. /************************************************************************/
    6 t. ~7 z2 }: E  d. i; I
  461. void DBSY()9 G: p- t4 C7 h3 n! M
  462. {
    8 x5 {3 E" a6 h
  463.         CE_Low();                                /* enable device */3 P  e! }0 R9 y. J5 B! i8 u& c
  464.         Send_Byte(0x80);                /* send DBSY command */0 T2 w9 b# V( p9 _
  465.         CE_High();                                /* disable device */
    # ^, b5 Z# S$ o# k
  466. }
    ( z1 e2 e6 S5 \2 G! p9 t: L
  467. 7 x! ^" Q: o+ O, G
  468. /************************************************************************/
    2 D% s5 X$ Y" B( h) J, ^7 H
  469. /* PROCEDURE: Read_ID                                                                                                        */
    4 o+ }0 i& I+ E$ e
  470. /*                                                                                                                                                */' \+ o5 |- E( ?9 A; p8 \
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */* r8 o! F9 g6 B7 C4 s6 H
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    ! Y$ j' G+ |8 B3 n# W+ f
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    1 f: z- W$ M6 @5 J. S
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    0 u) D+ F0 E: ]8 }' D, U
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    # i/ a. _, Y! J6 C& F' n
  476. /* variable byte.                                                                                                                */6 h$ Y: ?: x' @( O- l
  477. /*                                                                                                                                                */
    , r+ L* L" X) ^, [0 ?
  478. /* Input:                                                                                                                                */: J8 p) b4 R4 ?4 I
  479. /*                ID_addr                                                                                                                        */" _4 N( x+ X/ v
  480. /*                                                                                                                                                */
    4 F! O1 ~; t! l. R7 {) E2 w
  481. /* Returns:                                                                                                                                */
    ) v% [1 O8 F5 O" i% i
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */. A. @% R; @1 P4 |  x6 i% T
  483. /*                                                                                                                                                */, S( B- z; g8 i  I  h
  484. /************************************************************************/
    2 O# \3 T4 |- N" c; D# R$ o. S
  485. unsigned char Read_ID(ID_addr)$ o# B. I( C' v) i9 m4 P
  486. {( e8 w! z% o! O; o0 |
  487.         unsigned char byte;
    7 ]6 g) Z: A4 N8 V6 G
  488.         CE_Low();                                /* enable device */" v( h3 Q: Q( ]& B% \4 z* F
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    9 Y; t* {) Q$ t; a( C
  490.     Send_Byte(0x00);                /* send address */0 O/ Q2 N1 P* O, K; z; ~& T4 S/ r
  491.         Send_Byte(0x00);                /* send address */
    0 f# d  I- q9 c2 k, S
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */, Q  y: y* [0 b9 q$ v7 K( j
  493.         byte = Get_Byte();                /* receive byte */) |7 L' d9 y/ Y: t! W8 J
  494.         CE_High();                                /* disable device */" K# V5 A7 A5 A* \0 V: R
  495.         return byte;
    & ]0 E0 z7 S/ c7 Y9 k& f/ h
  496. }9 `1 z' Y7 e3 e+ T9 I" V
  497. * x: X& P) S6 }% [
  498. /************************************************************************/
    ; M, _& Y: Q# m+ ]
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    1 i7 u2 Q. c$ k9 X8 f& ~
  500. /*                                                                                                                                                */2 K) q! }7 n  V% f! C- V
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    ; H! P- G9 s+ ]& W
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */) C2 d7 |. v) r0 E3 K4 W" M
  503. /* Please see the product datasheet for details.                                                  */' |5 I0 q# g, u2 \  Y  ~' S
  504. /*                                                                                                                                                */
    / {1 E+ O- _! ^  i
  505. /* Input:                                                                                                                                */7 G7 H8 W! |' o. L% \
  506. /*                None                                                                                                                        */$ b; \! j' [$ J" N4 }
  507. /*                                                                                                                                                */
    ! E$ K: _* |# w' u% v9 C5 M: P
  508. /* Returns:                                                                                                                                */2 z) o* H9 {& l# a
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    / X# a3 i( T# g8 E# L
  510. /*                 and Device ID (8Eh)                                                                                        */9 C7 J1 J. H) f+ j! Q1 h+ X  K
  511. /*                                                                                                                                                */6 c( o/ R. w2 |  D$ q
  512. /************************************************************************/
    5 }7 _* j* H& M( }+ C
  513. unsigned long Jedec_ID_Read()
    9 P" O8 w% `+ X  r+ M. g5 j
  514. {( k" V. g/ e- D- E4 q+ e
  515.         unsigned long temp;
    ; @8 V# F+ x5 C8 u* v7 z
  516.        
    # k, a. i3 P/ `( T& @  D8 F  N: ]
  517.         temp = 0;
    ' a4 ?1 \: W7 s8 @

  518. 7 u, a+ S! N1 S5 ^
  519.         CE_Low();                                        /* enable device */
    9 q6 K4 C5 h: o# ?$ D& X0 ?) T- y
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */  o) [0 P& D4 b2 G
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */: ]; z# W9 T8 ^5 V2 w2 O
  522.         temp = (temp | Get_Byte()) << 8;       
    2 [# l& g0 {, h* Z" b8 B8 M  k& e* q
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */7 l8 A. T. S- ^9 y2 C1 r- Y
  524.         CE_High();                                                        /* disable device */
    9 w; c( ?4 n6 S

  525. 3 f, l- f$ w( Z
  526.         return temp;  m' _6 f) c- N% o4 R
  527. }1 j5 k, D7 I' f0 w( O4 T% s

  528. 1 e$ h& B. P/ c; x7 H
  529. /************************************************************************/
    ( ^# F; r. X0 a( e, Y- M# g+ s+ c
  530. /* PROCEDURE:        Read                                                                                                        */: w' q, U& `4 `
  531. /*                                                                                                                                                */                $ {% R( s: Y/ i2 _' k1 W  D
  532. /* This procedure reads one address of the device.  It will return the         */
    5 M% A7 B% F7 V! q8 n4 i% z
  533. /* byte read in variable byte.                                                                                        */
    $ Z: {2 a  A( ~6 s0 V4 ?
  534. /*                                                                                                                                                */& {5 q# u5 v1 G9 {5 \6 ?
  535. /*                                                                                                                                                */2 O8 D9 s$ V0 i
  536. /*                                                                                                                                                */3 F0 q, Q* Z0 u  ^: j- f4 y
  537. /* Input:                                                                                                                                */
    ' X7 V$ m) P9 h( k2 K* f
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    * N8 h. u% I( s' e" e1 K/ U
  539. /*                                                                                                                                      */
    ; n; B# L5 P8 Y$ E9 P! O) b3 [
  540. /*                                                                                                                                                */, X. O: N; }" c" V) I
  541. /* Returns:                                                                                                                                */
    / ~) [' f" X7 P6 G
  542. /*                byte                                                                                                                        */! N. [* x* c8 Q+ [/ _# L
  543. /*                                                                                                                                                */* V* I- O2 m8 `- D; B5 q
  544. /************************************************************************/
    + n( w4 {4 ?) ~6 F; G5 F( P' M% s
  545. unsigned char Read(unsigned long Dst)
    $ b. O) j7 J  T" m7 [
  546. {0 |) _5 T7 X" h* v8 _
  547.         unsigned char byte = 0;        ( }4 O0 j) w- @, \: f1 J3 K: H$ D: A
  548. 2 G1 P' p) ?+ s% H! ]+ ]* C
  549.         CE_Low();                                /* enable device */
    % }; n! J5 a+ b9 v! v
  550.         Send_Byte(0x03);                 /* read command */
    & ^; j7 W2 g8 a) U8 f
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    5 s/ ], P' ?3 a6 ?4 n' O
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    & ?; i2 `" E6 x4 T! |
  553.         Send_Byte(Dst & 0xFF);
    4 r0 E$ z9 A; R" S
  554.         byte = Get_Byte();
    , T  e. E4 D( A% m/ W
  555.         CE_High();                                /* disable device */
    % C- y  l2 ?8 F" Y, X
  556.         return byte;                        /* return one byte read */* c1 k. j/ F  a6 R
  557. }
    7 C: z1 N' e% N/ [  c

  558. ' z2 ^# [) W5 o$ Y
  559. /************************************************************************/
    1 d: Y6 Q) G5 M
  560. /* PROCEDURE:        Read_Cont                                                                                                */! ~3 k* I( k: S9 L- c
  561. /*                                                                                                                                                */               
    * x# z' M. a* l% {
  562. /* This procedure reads multiple addresses of the device and stores                */
    : z$ Z: x' B8 y* t7 q
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    4 S, g# R: n( ^
  564. /*                                                                                                                                                */
    6 l  c: X* z& a, J8 `% s! m/ m
  565. /* Input:                                                                                                                                */
    ( f) E) g, O9 o2 z
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */. s% ^" \0 T- C! M, H, U. z
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */4 V9 }- k( W0 V7 h
  568. /*                                                                                                                                                */
    0 ]6 N/ X. U3 H9 T0 Q5 @/ {
  569. /* Returns:                                                                                                                                */
    . G9 R" o% P9 m
  570. /*                Nothing                                                                                                                        */; ?2 N% I! ]: f$ z9 B
  571. /*                                                                                                                                                */2 \6 Y* s! F! z: `6 x" l/ D* _
  572. /************************************************************************/7 P  a$ \  v4 E& O/ j3 c+ p- I
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)3 v- i/ G7 I# u/ {( L! k( Y( |
  574. {: l; a, h$ B4 r% J* a5 Q( {
  575.         unsigned long i = 0;
    ; ~* `% m1 V3 ~
  576.         CE_Low();                                        /* enable device */: H. X* b0 \+ k. {* s" K2 C% J4 I, j5 ^
  577.         Send_Byte(0x03);                         /* read command */
    0 `( k6 K" `+ q1 R1 [% f7 X9 h
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes *// M6 h9 V( O: s- U# B4 q5 u
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    , `  u* ~; t; a4 ~( j' ^, J
  580.         Send_Byte(Dst & 0xFF);
    ( e/ v4 m9 x  e. E5 G6 r0 W- w
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    " f) r) i1 k  `+ l1 _! A4 Y# C3 q4 j
  582.         {  j- W: u, D3 n. _8 A
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */9 Z3 w! H2 o7 r- Q3 H
  584.         }
    % p/ V) |' ?% z7 I" }% @
  585.         CE_High();                                        /* disable device */
    : _3 T0 I4 D, D, N; @, d/ A
  586. - u5 X6 P. T! H
  587. }
    * g) O7 c: e/ M9 W5 j& G9 n% g% H

  588. * }2 {2 {4 z0 [0 n# p2 a/ p
  589. /************************************************************************/5 @- i( f2 `3 a% n9 Z2 y, ]6 k
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    % p$ s; v* ?9 Q6 n
  591. /*                                                                                                                                                */               
    4 P% ?5 A) Q2 I1 j% p8 c( ?( t
  592. /* This procedure reads one address of the device.  It will return the         */
    / r, \# \2 |0 R& b8 ~. D
  593. /* byte read in variable byte.                                                                                        */  d, K* _  W$ ]6 F$ M& R, \
  594. /*                                                                                                                                                *// J) D5 n; f0 h* E1 O9 o3 {2 a
  595. /*                                                                                                                                                */* S, r4 n8 J$ J: I" w4 b
  596. /*                                                                                                                                                */
    ; S8 ]) t& c. i% Y' T/ O2 ~' [& ~) y
  597. /* Input:                                                                                                                                */! M- G* N/ m( e6 O( _5 y
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    2 L4 S+ ~' Z5 I4 j
  599. /*                                                                                                                                      */
    2 ?5 W! ]0 F. u; }" w- P% W( R. y
  600. /*                                                                                                                                                */) |# S  W5 T" O# R4 Y* f1 V
  601. /* Returns:                                                                                                                                */
    " _* l5 J8 S. ?' d" V
  602. /*                byte                                                                                                                        */$ L8 D4 }. n9 Q5 ]% M& v
  603. /*                                                                                                                                                */, r$ V1 f% I) w
  604. /************************************************************************/
    $ O  z: |- `" A' S( Z
  605. unsigned char HighSpeed_Read(unsigned long Dst) % s  k: X! M  C7 {# w% d
  606. {- F8 m3 W4 L) {7 Z
  607.         unsigned char byte = 0;        2 Z1 g. X3 y" P0 B" y6 X& U4 Z
  608. 7 l$ _( {& m) z$ Q3 c
  609.         CE_Low();                                /* enable device */+ ^" R0 X2 b4 s' F
  610.         Send_Byte(0x0B);                 /* read command */) B; H) I* ]& x% @9 }0 I
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */' Z" ^) D" o+ C
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    3 g3 l( W$ h, [% l
  613.         Send_Byte(Dst & 0xFF);/ p, L# ]" Y& a" e  X' K6 c
  614.         Send_Byte(0xFF);                /*dummy byte*/
    # i& }# p% K. O! V9 w1 p
  615.         byte = Get_Byte();+ q  ]5 Q3 I0 y- L: i
  616.         CE_High();                                /* disable device */
    4 V1 o8 E7 o- H( g, W8 r
  617.         return byte;                        /* return one byte read */
    * y+ T# \  P: u; k* e" G" V
  618. }
    2 Y; f7 o- T; m% |: o- A  [/ y% t
  619. ' J* g1 P' ?( [+ r
  620. /************************************************************************/
    4 Q; ?: F& v( x) l
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */5 Y9 ]; g4 c' ]1 I6 y
  622. /*                                                                                                                                                */               
    2 V4 y/ y0 n, k6 G/ S; k  S
  623. /* This procedure reads multiple addresses of the device and stores                */
    6 c5 x# W' W9 P; D
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
      m$ S7 e, R: i* @" Z8 Y; c
  625. /*                                                                                                                                                */
    " l" y; h& U" L! c" D$ h! g
  626. /* Input:                                                                                                                                */
    # h, r5 _9 V( ]) K* k
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * x/ H" [5 x/ }& N% [( y/ F4 s( {
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    # i% v2 l. F0 w; V
  629. /*                                                                                                                                                */2 H7 \- \# k0 i4 j, s& d4 k! w7 N1 t
  630. /* Returns:                                                                                                                                */9 t5 \: `1 ?  N
  631. /*                Nothing                                                                                                                        */$ q. D8 P+ {! Y& `  w9 @: O
  632. /*                                                                                                                                                */. f5 p1 v' \( F
  633. /************************************************************************/4 }  K/ m5 u5 w" \5 J, e0 ?5 e
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    / J2 Q" N5 c" M6 A' n
  635. {; Q; A. \3 h# l+ F- a
  636.         unsigned long i = 0;% b  d6 L" C/ ^+ i: `1 L3 j
  637.         CE_Low();                                        /* enable device */
    + a- x& j$ |2 B! g
  638.         Send_Byte(0x0B);                         /* read command */! h% w! ^0 [; A) {
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */3 q1 w, @* M* X4 R
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    + v- [- ^; f8 `% O' r7 m
  641.         Send_Byte(Dst & 0xFF);
    * g# M! G6 I( R4 H7 ]
  642.         Send_Byte(0xFF);                        /*dummy byte*/, @5 W/ O- Z5 l
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */) {' M5 A" b0 z1 O2 Z
  644.         {
    ) {3 |. I0 F. {9 p% q0 |
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */+ {% S' d# x/ X8 W3 b* y4 o
  646.         }
    2 q; n# i7 {1 t  t
  647.         CE_High();                                /* disable device */
    4 {# d5 v( X7 U
  648. }
    7 d( {" Y& U- [3 F6 u
  649. . F# M" d" A6 o, [/ O' l" X  @
  650. /************************************************************************/; W+ y2 z+ t7 `
  651. /* PROCEDURE:        Byte_Program                                                                                        */4 G# i8 _3 T1 ?) m  ^, @
  652. /*                                                                                                                                                */. ^. H5 F7 f$ J3 R# m% J
  653. /* This procedure programs one address of the device.                                        */: ~& P; A- L3 z8 ?) A! i
  654. /* Assumption:  Address being programmed is already erased and is NOT        */1 w( l  ]* Y6 l+ {! A( A: Q
  655. /* block protected.                                                                                                                */0 j& j( t0 Y# R: f# a& j6 M
  656. /*                                                                                                                                                */1 x# Z6 K! e0 p, Z
  657. /*                                                                                                                                                */
    + s+ d- E7 x6 ~4 @
  658. /*                                                                                                                                                */
    1 L+ b1 `$ R" J: F
  659. /* Input:                                                                                                                                */
    * j% B/ v0 y/ C* h- J. E: o$ B1 |
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */, e' C# h: \+ \& e6 m  Y" H
  661. /*                byte:                byte to be programmed                                                                */* y( C( ~6 ^  ]0 i: i9 \  O. k
  662. /*                                                                                                                                      */+ `1 V+ ^) s) G+ _/ M" B! v( W
  663. /*                                                                                                                                                */; A! M) U7 |5 s1 p6 Z! n* V
  664. /* Returns:                                                                                                                                */
    ) J' i6 A, t3 J) M7 O
  665. /*                Nothing                                                                                                                        */& d; R3 H, u. @9 D
  666. /*                                                                                                                                                */9 A0 g: [2 [1 @/ l3 M
  667. /************************************************************************/( B" z# k, q4 U+ S  {1 p
  668. void Byte_Program(unsigned long Dst, unsigned char byte)7 r/ |2 @% T3 b) S
  669. {# Y7 |5 k4 n" a# M
  670.         CE_Low();                                        /* enable device */
    8 S+ w9 S6 p) M9 L# i
  671.         Send_Byte(0x02);                         /* send Byte Program command */7 S% W$ Y; p8 m/ t. v" C3 _
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    $ h6 c$ R) d0 K9 B
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));6 x- j. w. q( ~" m* c3 ?( S( q
  674.         Send_Byte(Dst & 0xFF);( w* Q6 r' `+ d
  675.         Send_Byte(byte);                        /* send byte to be programmed */! h; Y9 W' X5 v6 p# F! b6 q
  676.         CE_High();                                        /* disable device */$ ?+ [6 X* t: n$ z  {
  677. }
    / T8 V' D2 K; z) {3 ]) Z. u" j
  678. . J0 |1 v& F* v. `- c: L2 m
  679. /************************************************************************/7 x9 v/ @4 C- @* L# l' t! v: m
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    ' f, ?6 E5 C& h: z* @
  681. /*                                                                                                                                                */
    / {' Y1 W6 J4 G- o# C8 J
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/( R0 T7 ]2 I: V6 h# A, B9 B
  683. /* the device:  1st data byte will be programmed into the initial                 */1 L9 O- T4 H8 \4 j" r
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    # Y3 x# `- S, g; m. M7 `
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */0 ^; r0 l  K- p
  686. /* is used to to start the AAI process.  It should be followed by                 */% O& j. s& f* G: u8 L
  687. /* Auto_Add_IncB.                                                                                                                */9 M* ]# o8 T2 k8 M9 q( i
  688. /* Assumption:  Address being programmed is already erased and is NOT        */+ F/ Y; D5 |, [5 I! z8 Z$ u
  689. /*                                block protected.                                                                                */
    / q+ |" T. U; y1 _: C5 Y. l
  690. /*                                                                                                                                                */* H. M) ], @8 x  {% v" O- o
  691. /*                                                                                                                                                */
    % V8 P9 G* o$ N& u9 m; W6 J
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */$ l: n* t3 p! M& y
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */0 h& C! b; i' _% {: c: v
  694. /*         unless AAI is programming the last address or last address of                */, ~0 z2 c9 M% o  U$ @
  695. /*          unprotected block, which automatically exits AAI mode.                                */0 z) w* O/ i1 v/ Z6 t: r1 c, V
  696. /*                                                                                                                                                */
    1 n% S2 S" p1 r4 o
  697. /* Input:                                                                                                                                */( P* l/ m' w2 X! C0 z" q- c
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    % F* Y8 c  N3 ~
  699. /*                byte1:                1st byte to be programmed                                                        */! h! a- ?7 t3 |8 E) ]/ s
  700. /*      byte1:                2nd byte to be programmed                                                        */
    - p$ L8 m+ ]+ Z  h% I# q3 C
  701. /*                                                                                                                                                */: }6 K2 q: m" `0 ~( j
  702. /* Returns:                                                                                                                                */  _# }9 j& k; n7 M
  703. /*                Nothing                                                                                                                        */
    + L( u1 Y! b+ B! ?1 B* W% t7 |% f
  704. /*                                                                                                                                                */$ X3 q8 `/ {8 h
  705. /************************************************************************/
    5 c* K6 s- P' v4 g  {' z
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    , R" a3 G7 I/ r( E0 Y4 h/ m- o: C
  707. {
    $ I- F, _; T& G. B9 U
  708.         CE_Low();                                        /* enable device */
    : M( S8 K3 ~3 `6 A- W! `
  709.         Send_Byte(0xAD);                        /* send AAI command */
    ; D4 K7 W' o0 A* M3 J  V1 k
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */+ d1 A0 D7 E9 X1 a* O
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));/ P* ?8 o; Z+ \' m. A; J: K4 m: C# Z
  712.         Send_Byte(Dst & 0xFF);
      F3 {6 l  ~4 b. w1 z
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        , C, |2 ^4 v, o" i
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    $ v7 L! U! i' \3 j
  715.         CE_High();                                        /* disable device */
    0 Z4 Z& s# {( @
  716. }8 b/ R# l, e$ @- u
  717. * J, f* ?- g- h9 _
  718. /************************************************************************/. M2 q3 q6 f8 M* X% e7 l
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */1 V9 V7 v2 n5 c8 L" l$ B( f$ ?" N8 U4 V
  720. /*                                                                                                                                                */
    - G, s3 E. H; W6 M
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    $ `3 r7 O& D  q' j6 Y: l
  722. /* the device:  1st data byte will be programmed into the initial                 */) y1 o$ v, n5 F0 I: x% G
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */0 j/ G0 i. J+ f! _& T: I( b
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */' h) K2 I. j+ r1 j6 B( {, `
  725. /* is used after Auto_Address_IncA.                                                                                */  _! ^( E7 J% y, w& E
  726. /* Assumption:  Address being programmed is already erased and is NOT        */1 h$ E9 g" w7 C' l7 r
  727. /*                                block protected.                                                                                */, Y, v5 }+ c6 @7 |4 z/ c( N
  728. /*                                                                                                                                                */
    $ o. \7 k& u, u* `* M: D
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */7 c  j, g1 p1 R1 O
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */% q" @( ]& T) [5 }$ J( w8 q
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ! N  I# e1 w8 O; k) y8 M& K
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    : `6 T1 K* y) }( z% a
  733. /*         last address of unprotected block, which automatically exits                 */) {3 J2 U  p, h
  734. /*         AAI mode.                                                                                                                        *// N9 d$ m* ]3 K  w6 u, w) g
  735. /*                                                                                                                                                */; L( F0 i. @  b7 I3 H& L6 S& W, `
  736. /* Input:                                                                                                                                */) f0 }* l4 d  |- R6 u$ z7 I3 p
  737. /*                                                                                                                                                */
      U+ w' k4 s0 |& V6 O
  738. /*                byte1:                1st byte to be programmed                                                        */
    ! x( w# y; b2 }, a, ^% i
  739. /*                byte2:                2nd byte to be programmed                                                        */: ~' F; B; h2 ~8 u0 [7 ]0 E
  740. /*                                                                                                                                      */' N" Z% o+ x( L1 N- p$ g
  741. /*                                                                                                                                                */
    ' K" o$ \# s% m; l
  742. /* Returns:                                                                                                                                */& C9 Y6 m9 {5 P1 R( h
  743. /*                Nothing                                                                                                                        */% V! t& l1 A9 l8 @' M2 X
  744. /*                                                                                                                                                */
    , K  M) V% m& L( n. o
  745. /************************************************************************/
    ' w0 Y! g; a5 s3 h  N. w; i
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2); s, d2 m8 P& H. e8 o* `
  747. {8 t! @9 I$ H# ^/ ^$ P7 w2 e
  748.         CE_Low();                                        /* enable device */
    9 a* `7 |& z) I
  749.         Send_Byte(0xAD);                        /* send AAI command */8 r# ^' F! k7 Z, l/ o- {, E9 k2 w
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    ; a" X+ {+ q) U* Y1 t. y) K
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ( |% W: ?' u# h. I+ M6 x
  752.         CE_High();                                        /* disable device */" U7 n, y1 D+ f+ w
  753. }
    / i9 R2 a( j6 Z" C5 J7 ?

  754. 7 l2 x% v# v  I3 G; f( l9 d
  755. /************************************************************************/0 `4 T' Q* A; ~; v1 b5 d' J
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    9 _4 p/ N4 Q5 \8 B
  757. /*                                                                                                                                                */
    ' h+ {5 f8 P1 s
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    + S. b) z" Z6 z8 ?1 ]
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    7 r! q4 i; [5 l& \$ s  A" N" `: e
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */$ D% q' I+ t" H# B& P$ \: l5 P
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */1 P* X* `; h7 x7 _! r
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */+ m* X# R5 ]( ]3 p" ^! O
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    % P0 N9 |+ h- J. b& W
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    0 _- w9 S1 E: Q5 q
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    : K( p3 ~9 t/ N1 D
  766. /*                                block protected.                                                                                */7 H  N7 C9 m- A5 u
  767. /*                                                                                                                                                */4 z. N/ z  @+ f4 e# A& V3 j
  768. /*                                                                                                                                                */
    9 a9 J3 H+ g3 z1 T! X( B1 C
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         *// O9 [3 l, ?" e& \0 [; t
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    " t2 D' O# @+ Z& E9 i7 q) ?
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */- v* `2 U$ ]8 z% g2 L1 C$ v- S
  772. /*          to exit AAI mode unless AAI is programming the last address or                */0 l0 ^% M! T' n0 o1 o; y6 V1 v6 j$ ?
  773. /*         last address of unprotected block, which automatically exits                 */
    - @; [( z0 R; W% O% E
  774. /*         AAI mode.                                                                                                                        */
    ( N- b- x  i  }
  775. /*                                                                                                                                                */7 Z2 R& a. r3 J1 A
  776. /* Input:                                                                                                                                */' @+ ]; O7 j, ^+ b: H
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */6 u7 ^% y1 }. [% U* W
  778. /*                byte1:                1st byte to be programmed                                                        */7 `# Y/ O; t! i, p% z' J. X
  779. /*      byte1:                2nd byte to be programmed                                                        */# s: }; z! n3 Y+ ?# I
  780. /*                                                                                                                                                */* s5 r: q; h- K  s
  781. /* Returns:                                                                                                                                */- S# d: O/ @' h; t4 c8 b! u. ]
  782. /*                Nothing                                                                                                                        */! t/ q! t7 i6 U7 t5 F' A
  783. /*                                                                                                                                                */
    3 e1 {# F, \7 x
  784. /************************************************************************/# W. j; t! t" d9 i8 P$ p! e
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)  T: e7 a( V& b" G
  786. {
    ; T5 y; n  [! ?+ \, i
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    0 ^. S& N3 f& p# w& @

  788. 2 V% ?/ K, ^- `) ?  h- M
  789.         CE_Low();                                        /* enable device */  c8 d3 s9 u  w2 I! {9 v6 U
  790.         Send_Byte(0xAD);                        /* send AAI command */
    1 ?0 G4 y8 a6 {" H! N( i9 \; ]! l
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */0 w' i: H" D9 q. J0 w6 P' V5 r
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));5 @+ `* t% P- _( R9 f: V3 q  m
  793.         Send_Byte(Dst & 0xFF);/ d9 S- M1 c) I* C# m. O
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    * V1 }- g* Z; ]3 q
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */- D6 T( l$ c& k. g4 ~* i% Z
  796.         CE_High();                                        /* disable device */. y4 O  i) I2 F5 |5 `+ S' h
  797.         1 M) p; @' k$ G: h; E# Y$ v
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    / R  k6 M0 k4 X

  799. ) I% _  c9 t" t! h
  800. }
    . n. X& l+ H4 g. R; T# x

  801. 0 Z* R# p/ D+ q* s
  802. /************************************************************************/8 C* C9 v0 M! M
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */- G* q) P  L2 \
  804. /*                                                                                                                                                */& {6 I9 P% X6 W3 K; K2 J
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    ' p! G0 D6 A2 p  I% P* E, }
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */4 G5 S- k& M% f# W- l& ]+ b9 {
  807. /* AAI programmming is completed.  It programs consecutive addresses of */' H$ J# @* R+ d2 H5 ?, P
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    & ^0 T' I9 G" R; w: m
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */  q6 k; S$ t' T5 u
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    , A9 n, t0 X- h
  811. /* used after Auto_Address_IncA.                                                                                */
    / I- V: V+ g1 Q' N
  812. /* Assumption:  Address being programmed is already erased and is NOT        */$ Q' q' ~8 P3 O' |. F9 u* K
  813. /*                                block protected.                                                                                */! v: n8 u" M: p$ q/ I
  814. /*                                                                                                                                                */4 |4 \8 |4 Y) i0 i" c
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */. l% @+ ^4 S) A+ A$ F: g+ J0 e4 i1 O! e
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */5 H, e' R# F* ~" S8 i2 z
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */8 K. e! H. X, n9 C8 Z2 \+ H
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    ( T( Z3 r: |. J4 ^% y
  819. /*         last address of unprotected block, which automatically exits                 */
    # i4 p0 a" h% ]' F
  820. /*         AAI mode.                                                                                                                        */" G; x4 _* V$ F9 r
  821. /*                                                                                                                                                */% b; n' x+ e+ ~& Q
  822. /* Input:                                                                                                                                */6 a5 I- {( n; O
  823. /*                                                                                                                                                */+ E- K) J2 {& Y2 L- {, j! B6 g: H' S
  824. /*                byte1:                1st byte to be programmed                                                        */
    7 ]: ]; I7 l1 W
  825. /*                byte2:                2nd byte to be programmed                                                        */+ G6 h4 X  r, P% B
  826. /*                                                                                                                                      */
    ; `- c6 i# D) l0 X* S5 B/ |* c
  827. /*                                                                                                                                                */
    5 M0 p. A9 U7 A
  828. /* Returns:                                                                                                                                */+ Y1 g9 v7 p* x
  829. /*                Nothing                                                                                                                        */& z0 w) Y1 {7 z! @; F3 O% [* e3 J
  830. /*                                                                                                                                                */
    2 a0 k2 ], G- y$ ]* b7 ~& r& m  t1 `9 W
  831. /************************************************************************/2 V' c# O! Z3 l( g+ J8 I
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    5 }: ~8 V+ P1 v! @+ e
  833. {
    1 Z/ g) ]/ k. F& |
  834.         CE_Low();                                /* enable device */, e4 k" f4 p3 {- N5 w1 I9 R. \2 J
  835.         Send_Byte(0xAD);                /* send AAI command */4 p7 f4 r# N# t1 h& E
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */4 h/ ?2 ?1 @" W7 }
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    9 C- h/ i2 h: t2 Y6 {
  838.         CE_High();                                /* disable device */  ~' h4 q* l- M
  839. 8 e; v' O! _# E# F# u
  840.         Poll_SO();                                /* polls RY/BY# using SO line */* {# ~3 Z' u* ^1 p& i2 H* D2 }( F
  841. ' x1 ~; d/ [6 W  ^4 a2 f
  842.         WRDI();                                 /* Exit AAI before executing DBSY */2 C- k$ C7 P  k
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    4 m) k+ E5 Y9 l0 N; W! T9 A% ~
  844. }8 G2 l1 ?7 l2 U) ?9 e

  845. * c" F) K- L6 `* N$ y: d% W# p
  846. /************************************************************************/4 e& f9 b% b0 s6 `
  847. /* PROCEDURE: Chip_Erase                                                                                                */# a: E) E; v* \& D
  848. /*                                                                                                                                                */
    " v9 w8 t2 u5 X) L
  849. /* This procedure erases the entire Chip.                                                                */
    0 W7 N4 `5 g1 R+ @" v
  850. /*                                                                                                                                                */
    # v* W( R7 _# a8 X( E0 H( X
  851. /* Input:                                                                                                                                */
    4 D( h( i: ~' z* t8 ^- e
  852. /*                None                                                                                                                        */
    8 i& [$ S1 g  ^
  853. /*                                                                                                                                                */
      E2 i* |! X# E0 d3 m+ z9 c& X
  854. /* Returns:                                                                                                                                */7 g6 e! j. s2 R. z1 F# q; X
  855. /*                Nothing                                                                                                                        */
    0 y, A8 S, ?1 H0 Q
  856. /************************************************************************/; I' O& w% N. L1 m! K3 W, m3 V
  857. void Chip_Erase()
    2 N/ a4 E( _5 X! |( z# |
  858. {                                                0 e3 Z( J) }# o
  859.         CE_Low();                                /* enable device */
    * q0 O& t) F* o/ d9 U$ ~# X
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */! E* W/ A* g  v' J  F8 e7 y- ]
  861.         CE_High();                                /* disable device */8 K/ s, r# @" g/ d$ m, ?8 q
  862. }
    4 T1 n8 P" ]3 R" @
  863. 9 Y, Y  @( y- z
  864. /************************************************************************/
    ! Q9 [2 p0 |7 x1 c& c0 f1 t
  865. /* PROCEDURE: Sector_Erase                                                                                                */8 h" W$ n& ~! m7 |& A  O! w8 t
  866. /*                                                                                                                                                */( z* m: X4 S( b* r
  867. /* This procedure Sector Erases the Chip.                                                                */! k6 h$ |$ S" N  r) y
  868. /*                                                                                                                                                */* |3 W$ e+ \3 D
  869. /* Input:                                                                                                                                */
    # l4 C" d. W# {+ u, u" g- w" h
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */; W, M& ~8 o2 \6 C
  871. /*                                                                                                                                                */
    2 S4 [- a  V2 }. D; l' a. ?
  872. /* Returns:                                                                                                                                */
    + I) n  p2 O% s) p+ V
  873. /*                Nothing                                                                                                                        */
      y" ?4 u8 h! @5 o
  874. /************************************************************************/" w8 @+ n3 ~. l3 h- a
  875. void Sector_Erase(unsigned long Dst)
      y3 ]$ U' v4 Y2 U6 }
  876. {2 C5 w$ _2 q- i" m! F+ r
  877. % _; o# C( a  @8 @% u; l

  878. ( O: j# w% V3 T" v9 j" A
  879.         CE_Low();                                        /* enable device */
    : V2 e* |# H$ B
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    . \3 Q  [5 M/ P8 s: U' u
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */% ~, F1 K7 M& ?; B  d6 H* Z6 s' R/ E
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    4 j9 Q, L3 x( `, r
  883.         Send_Byte(Dst & 0xFF);) P' O8 G( z* ^
  884.         CE_High();                                        /* disable device */, A: O: L4 U4 f* N* }, o
  885. }        ; m3 n) z. n7 g4 N8 N

  886. . c( A/ c5 s: q4 X
  887. /************************************************************************/
    ' A  N$ L3 h$ T/ w8 s( Z0 T" ^
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    # h5 ?8 W) x- I* D1 n1 o3 p* a& M
  889. /*                                                                                                                                                */7 k, u  v& J; ^$ d; c& N
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */6 p/ o+ w) \6 d" b" V/ F, Z
  891. /*                                                                                                                                                */
    4 a" P; C" _% ~2 X; w
  892. /* Input:                                                                                                                                */! Q5 M4 s1 U5 t1 o8 R7 M3 \6 m
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    4 f' S6 c! x% `; Y8 J
  894. /*                                                                                                                                                */
    0 t! O! U/ O6 g2 N- k& Q3 Z
  895. /* Returns:                                                                                                                                */
    1 \# K, [7 T. G1 [9 A
  896. /*                Nothing                                                                                                                        */) g8 y! G( t, G, H6 w
  897. /************************************************************************/* A" V  b: L9 `; T& c2 L8 Y
  898. void Block_Erase_32K(unsigned long Dst)
    ; y/ `2 O+ s% c; K, Q5 Q
  899. {
    , ?0 B  y- t$ a7 U. ?- d
  900.         CE_Low();                                        /* enable device */, T& ?8 a) U. ~
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */0 f2 _3 f( S. `' e
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */( b' Y7 G+ i1 o6 ?& M, d9 D
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));" c! N' L" h) e$ Q' W2 G$ p
  904.         Send_Byte(Dst & 0xFF);
    0 q9 R9 m7 U$ Y( R  W0 j3 H
  905.         CE_High();                                        /* disable device */
    4 M; x& P+ {* j6 k
  906. }
    7 i. S$ e5 F& S0 G& v( g: u
  907. 8 {3 y1 F% V' m
  908. /************************************************************************/
    ) }) N' p) r8 k, J5 S- r
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    / R0 F: b2 F9 ^4 _: e8 S
  910. /*                                                                                                                                                */: R* v4 C# w! l+ \" L  {* e
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    , o7 n; r1 m  o3 b, o0 A
  912. /*                                                                                                                                                */8 E. w" d9 G6 y4 K) P+ v( \- N
  913. /* Input:                                                                                                                                */
    * _  }: R# ~4 a
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & ?. a' a7 e  D% _: L' _
  915. /*                                                                                                                                                */
    5 x. w1 y# K3 h0 W
  916. /* Returns:                                                                                                                                */7 j# u8 ^" f$ ~# V2 C! ~7 Q
  917. /*                Nothing                                                                                                                        *// S  i2 i% q2 c& j& d
  918. /************************************************************************/
    8 b0 r- W& E5 q' v5 x& _. f
  919. void Block_Erase_64K(unsigned long Dst)
    # ?& Q0 `; a$ m& b( v
  920. {
    : r/ S+ F4 H; Z9 w- I5 B* o3 d9 f5 ]. N
  921.         CE_Low();                                        /* enable device */
    3 d: e; Q  d$ D  L. r0 j" {$ P* Q
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    / o' [- b+ I  Z/ _2 ?' L
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ' T* n$ Y4 ?% I( ^
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));  C0 g4 V4 ?9 L( j9 Z
  925.         Send_Byte(Dst & 0xFF);
    9 g, b* S3 L- f* H8 G: L
  926.         CE_High();                                        /* disable device */: c! C) O2 w8 o! j, w0 ?5 x# @
  927. }0 H5 D2 v. ^3 }/ d$ n) J

  928. ) X4 T$ {- k# f: c/ F- Y# g2 m
  929. /************************************************************************/4 c+ r8 k6 |9 F6 ^. R3 b
  930. /* PROCEDURE: Wait_Busy                                                                                                        */( F% X7 Y4 M) w1 i5 v& B
  931. /*                                                                                                                                                */( D# _) |! D3 H( T5 m) B" K
  932. /* This procedure waits until device is no longer busy (can be used by        */$ s8 a( P, u7 ]9 B; M* u! C
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    ! k' q; e6 n4 c
  934. /*                                                                                                                                                */3 F/ h9 W  S( o% [5 `7 I* ^9 j
  935. /* Input:                                                                                                                                */
    : q6 S' M1 u4 L+ X! q
  936. /*                None                                                                                                                        */: s$ X1 L! I! l9 |' f, a. s( f
  937. /*                                                                                                                                                */, q& M! b8 C' P- H2 R! g
  938. /* Returns:                                                                                                                                */
    . V/ O% ]' k6 `1 L
  939. /*                Nothing                                                                                                                        */
    9 R/ }1 W$ @1 z
  940. /************************************************************************/
    8 x4 Z& J5 V: S' _9 z
  941. void Wait_Busy()
    % Z# M5 q5 V8 h& X: l1 _/ S: n- w
  942. {: ]8 ~! ?# r! c' @4 Q
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    * o& @! Q  K7 K5 y  W/ L7 H7 i5 i
  944.                 Read_Status_Register();
    8 J  f  ~2 P) @, O; ~3 J( n
  945. }: I8 X$ R4 B. e0 S( E0 G
  946. ( z9 b+ c/ z2 D5 ?' Q
  947. /************************************************************************/3 w# j2 g, t" }/ N9 W2 b: {3 R
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    3 h* T$ r) C: c' G6 V( h
  949. /*                                                                                                                                                */) t: J4 F- O, h7 Y8 \4 ?
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    * ?) _" H: N, K% f+ R: l7 L
  951. /*                                                                                                                                                */
    3 W* V  z# ?. t, ]: H0 O. u) j7 _, K
  952. /* Input:                                                                                                                                */% m" ]2 A! O; I% H
  953. /*                None                                                                                                                        */5 C5 B! r) j5 l  H- x9 B- k
  954. /*                                                                                                                                                */# n/ H- {. p4 x8 X8 S. i+ L
  955. /* Returns:                                                                                                                                */: {6 ?$ D* [( ^) w& v9 o. {2 L
  956. /*                Nothing                                                                                                                        */; S' ?9 V0 ^5 S* i' o
  957. /************************************************************************/
    8 ^# x% S6 v* R" d) Z" e) Y' b, U; W
  958. void Wait_Busy_AAI()
    / C! c2 k1 R, ]
  959. {: c& M- x9 G0 |6 u
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */& I% s4 I: D  U6 Y5 S
  961.                 Read_Status_Register();3 L" O2 [2 u" {% P# G; ]+ I9 h
  962. }9 C2 ~1 ~, N2 l7 M1 z' c& ?
  963. 5 ^: q+ _1 \) Q/ v3 c0 w5 Z5 w. c7 T! Z
  964. /************************************************************************/
    " k+ v. K& h  j; m+ C( M
  965. /* PROCEDURE: WREN_Check                                                                                                */# p8 k' m: p7 s8 p
  966. /*                                                                                                                                                */6 \8 p- |5 S. |
  967. /* This procedure checks to see if WEL bit set before program/erase.        */  l% J% L( Z) R6 {* L
  968. /*                                                                                                                                                */# I' X$ o; N  o& b% [9 G: E9 R
  969. /* Input:                                                                                                                                */+ j! G8 G) z4 C: [
  970. /*                None                                                                                                                        */
    . d( Q% H' h  R$ X  n
  971. /*                                                                                                                                                */
    ; d9 z& F5 _8 q# _8 i9 O
  972. /* Returns:                                                                                                                                */9 x8 J2 p( V) a8 Y! w4 I. j
  973. /*                Nothing                                                                                                                        */
    # Z- A7 \; X* t5 N! x: Z  L
  974. /************************************************************************/
    + o( ^, X! \2 [3 F1 W$ H  h0 q
  975. void WREN_Check()
    2 o, X# w, j" _0 H9 [) B
  976. {
      [6 d* \: l7 y6 L9 s) C7 v
  977.         unsigned char byte;/ @2 R9 N2 p, g# N! r
  978.         byte = Read_Status_Register();        /* read the status register */
    ' g- k4 S2 N9 m0 _. ?
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    1 q, p8 ~+ e/ F2 a' g
  980.         {
    1 |( H. u+ p# x8 M6 J1 d
  981.                 while(1)
    ( g& w$ i% p; ~" V9 B
  982.                         /* add source code or statements for this file */
      x) u$ r$ r$ Q" O8 O
  983.                         /* to compile                                  */6 _) Z/ p/ A& x1 D
  984.                         /* i.e. option: insert a display to view error on LED? */. ]$ v; ], C! d1 ]+ f; a
  985.                  # h4 ^# T( X5 {" h2 |+ D
  986.         }7 z2 @: I& t( P4 A% a6 V/ v' o; C- c
  987. }' A4 _6 H$ u/ v! B% w3 G

  988. / v7 K) _2 Q( Z$ `  [- u
  989. /************************************************************************/2 \8 y7 Q: _# W. O
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    & x& U3 ?: |$ |
  991. /*                                                                                                                                                */8 E" w" i' k( p5 m6 b8 f7 N
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */' }( A8 t' L: q" p5 x9 j
  993. /*                                                                                                                                                */
    " R1 o, {! |5 K! b' M) N  t* l0 ?
  994. /* Input:                                                                                                                                */: y- T: y; K8 E  g$ M+ w9 c' b) b
  995. /*                None                                                                                                                        */; {4 }7 }# y* i
  996. /*                                                                                                                                                */
    4 y; [1 k6 H; ]# ^+ L. H$ X
  997. /* Returns:                                                                                                                                */
    ; e2 ^' Z9 b  Y: \4 N% i
  998. /*                Nothing                                                                                                                        */) w- w6 m) u. {+ A
  999. /************************************************************************/
    ' f" f) B  w1 e) A/ j. {
  1000. void WREN_AAI_Check()+ ~" ]$ ?# ^3 r
  1001. {8 ~# w; A; \) z4 P: Q$ W/ m
  1002.         unsigned char byte;/ V8 L4 p. A* S3 k1 G9 h7 y: z" V
  1003.         byte = Read_Status_Register();        /* read the status register */
    ( C) Z3 `& |! w& l- t) K, l
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    : Z1 l* D; q$ m
  1005.         {
    * I5 _  F3 G, l0 r9 h6 V
  1006.                 while(1)               
    4 J$ A& `* {8 a0 m4 W: l; Q5 _
  1007.                         /* add source code or statements for this file */+ f/ Y+ t/ m4 @% |: g2 A
  1008.                         /* to compile                                  */5 F, w( I/ e# b/ y+ r
  1009.                         /* i.e. option: insert a display to view error on LED? */
    * ]) k  \% [- I8 Y

  1010. $ q' a/ y. L/ k6 j$ ~8 T2 z- ~
  1011.         }
    4 g3 E. W* {2 P! Q# g9 ?- ~5 F
  1012. }
    3 \# o5 T) Y3 \! ~
  1013. 1 r% a1 k" @4 \5 r# W
  1014. /************************************************************************/
    " B: |3 d- g* {. u$ R$ ^
  1015. /* PROCEDURE: Verify                                                                                                        */: j: q2 G! H5 p
  1016. /*                                                                                                                                                */  Y/ @: G. z& U
  1017. /* This procedure checks to see if the correct byte has be read.                */7 I. y( ]) I, H8 y- W4 w9 C
  1018. /*                                                                                                                                                */
    ) K8 |: s0 l+ S1 ]! [7 \) i& a; W
  1019. /* Input:                                                                                                                                */
    8 d* N. f$ T8 J) g, f& D
  1020. /*                byte:                byte read                                                                                        */- s0 G1 f4 x( z$ i) g8 w# t
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    6 i" q! k6 f* f) z
  1022. /*                                                                                                                                                */
    ! ^4 V- h7 f, l- m& `5 W; P
  1023. /* Returns:                                                                                                                                */5 Q9 X+ ~; M4 e2 n
  1024. /*                Nothing                                                                                                                        */
      k) e- G/ R8 ~* A' p' x# F
  1025. /************************************************************************/( J8 ?, G# ~1 G% M3 K
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    ; B8 \7 p: G5 C7 s; V5 a# @  R6 z) _- v
  1027. {
    3 W- O7 F4 w* z7 ], z
  1028.         if (byte != cor_byte)/ O, z- {: _  n( B) _9 |( h
  1029.         {7 Z; S3 q4 ^6 h; i1 Z
  1030.                 while(1)
    1 C7 v5 u  _8 d* r3 c) G
  1031.                         /* add source code or statement for this file */
    $ N& q- p% r4 z! L) q" ~
  1032.                         /* to compile                                  */+ d3 ^4 q7 C" E, n, `+ J, n
  1033.                         /* i.e. option: insert a display to view error on LED? */. H2 U# ?+ C$ U: w: V
  1034.                 " h) C2 l# K! t9 q# a7 q  Q
  1035.         }4 ~2 [8 H3 a4 w
  1036. }7 L( \3 q* R' Z( B# e: z
  1037. 9 F% @* m0 X# D+ F- d

  1038. % k' G! P* p' w' c! O: G
  1039. int main()
    5 C2 G; t! m$ B& L
  1040. {
    . L# u. w9 G4 c# x; p0 H9 n1 r

  1041. # E5 G+ q1 t. K, G) b+ ^/ V
  1042. return 0;
    : K* Z7 h( C: A9 U& F: I
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:* N- n( f$ {) M
   main()
6 \: R9 ^( h& p$ `: D. Q7 X   里面怎么是空的呢?4 r: B3 V9 I, U; O: z/ }9 H
   发一份给我吧" o. P9 m. _. k( v! z7 s
mail:luyijun2005@hotmail.com
! w/ b% R4 G- X咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
! ?, `' q0 _$ ?; z# P) u
: G* x. {) u! z! C+ D! S" l; k[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。% w4 Z& ?9 d' j; f7 a- ?
EC的代码在哪跑,你看DS的说明,每个EC都不同的。
/ o  f  x9 t6 t, C- H, D" q" h) KOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
; }+ o* a1 h2 ?# o! R上面几个问题是你没看任何东西而白问。
* ]+ f8 B/ z3 X( h2 r! j/ U/ x* i" z
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。, a! B. q  w! ^3 q4 l3 l+ Y
5 ^" [6 X7 Q0 x% V, E: @
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!* t9 a4 D6 @  e. I* H  V$ k

# R! V2 Z) }3 {关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”. S; X2 P) h' S
$ M: G* C$ E: O! k
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
" e' C6 c( m% l6 M
7 A& E9 \/ Z# w$ ^$ W3 r+ s  t不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样9 `8 B4 c. G9 I- Y) r
似乎要把SPI能support 到最大,这EC chip应该有好卖点
6 D, {5 z$ ~! O7 a$ K( LBIOS功能要不要强大,也就决定了SPI Flach的大小
/ R% U/ s# t/ l5 J. r我是这么想的~让OEM去决定要挂多大!' ^/ w7 O+ m/ \
如果我司有BIOS工程师就好了~哈0 N, t7 h; z; u& r" |2 z) b, C$ Z! G
WPCE775应该算很新的东西,来看它支持到多大?' x; n3 B, T$ c. g

. I5 \, j8 ^6 p6 Z, ^另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte) q, X; H3 n* j3 }/ c* v3 V; g
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.: z2 z- P( X0 c8 O

4 n  K+ _/ a1 e: W% e! I这份driver收下~希望以后有用到! i9 t, `. x% x3 S& q2 c
谢谢bini大大
8 D# z4 ~4 i$ m2 Y8 N/ o  i+ |. t! e( r8 I  X
很新很新的新手,如有错误请指正 (准备看第二家的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(). I  U9 ~( L/ W. r, t
{
* D/ t$ G. h3 z( t( i3 r. H        unsigned char temp = 0;
, ~9 a: [! M8 B# ]; n        CE_Low();
8 d- l( `2 S2 d0 l$ X    while (temp == 0x00)        /* waste time until not busy */
$ _' L- U' N" B8 b7 g; B9 e7 @                temp = SO;
' f( z5 M9 }8 b$ f% `7 F4 I9 t) h        CE_High();
. L9 Y! U' V, v}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
4 i* V2 W% X9 X8 L* o; f{$ ~# V6 r* @. R# y! ?5 i6 z! M1 P1 T6 G
        . S  t; \( W# l7 i  i- u8 n
        unsigned char i = 0;
; W; M7 B2 v; A) ]% j/ n3 {& i        for (i = 0; i < 8; i++)9 ~. f: s( T8 o, E$ S* P% S3 x
        {9 K0 M. n# B1 y3 b" e/ F) w: L
               
1 }8 B9 f& o' D4 w                if ((out & 0x80) == 0x80)        /* check if MSB is high */6 t( b/ h  J2 o- q2 `1 L) A4 I# n
                        SI = 1;
4 [4 K. l/ y) i" C2 R                else
( O. _  l& {3 K" a                        SI = 0;                                /* if not, set to low */' M' `) u/ u( o0 k" Q' N- z% A
问              SCK = 1;                                /* toggle clock high *// z, e0 V$ D! z. n% u" I
   题            out = (out << 1);                /* shift 1 place for next bit */
; j. f7 H. ?% g6 [' \5 I8 g# T) g( M                SCK = 0;                                /* toggle clock low */
) g( `/ N* c: ?. M        }% T1 ^2 B6 i  s) |# h
}$ ]! A/ _1 n& v! M& p+ p) X8 A; Y
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-4-6 17:34 , Processed in 0.141778 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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