找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54048|回复: 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
    " p  h- F! J+ k, [; F* ]/ G

  2. 8 y, F/ z4 }8 S4 n: V9 l8 Y( \
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    , P! M& H- }3 [0 ~& f
  4. ! F2 {. P* q) F3 ~7 E+ @/ q& V
  5. November 4th, 2005, Rev. 1.0) Y) ?0 P& Z( W3 u  ^+ y& N; }

  6.   D- {/ ~' V& G
  7. ABOUT THE SOFTWARE
    & F  I+ F, l/ I. _+ q: O
  8. This application note provides software driver examples for SST25VF080B,) K/ V$ [; w+ r; C! y
  9. Serial Flash. Extensive comments are included in each routine to describe
    3 x" @$ E6 q$ }. M# z
  10. the function of each routine.  The interface coding uses polling method
    ( t9 `' j, X" g" F$ }
  11. rather than the SPI protocol to interface with these serial devices.  The
    ; C+ C7 ~2 v; Q( ~3 H+ s9 H( _
  12. functions are differentiated below in terms of the communication protocols
    . K+ \5 b+ W1 u0 J
  13. (uses Mode 0) and specific device operation instructions. This code has been
    2 Y0 m, r1 a% \
  14. designed to compile using the Keil compiler.% p. P! h4 t8 o3 U9 b( C& P; d5 o) r

  15. , o9 T1 D) r) J. k* ?

  16. 5 F! w- O) }3 |- S
  17. ABOUT THE SST25VF080B
    9 C' A% e6 I% v" Z6 f9 w/ s

  18. : h# T8 V7 Y; q) v8 F7 Q! y! V+ A4 d
  19. Companion product datasheets for the SST25VF080B should be reviewed in 2 f  L3 L$ L# `7 c- J4 o
  20. conjunction with this application note for a complete understanding 8 t6 W+ r* @/ N5 O" J* Y3 q$ n# Y* M# Y
  21. of the device.
    6 N. f; v- P8 C, k% ~( C- Q. F0 U0 K  |
  22. 3 w, [/ K. G: H) ]5 ]- B  i8 S
  23. : \! s) G% J- n* C8 A
  24. Device Communication Protocol(pinout related) functions:- i. @$ h4 H0 w- t$ x5 y

  25. - z' s& _- T- Y/ V( U1 ?
  26. Functions                                    Function) |+ e0 f, |) y$ z+ ]
  27. ------------------------------------------------------------------  u0 v" v6 Q9 d$ l
  28. init                                        Initializes clock to set up mode 0.
    6 ~. N: e! n) k% v- X& j
  29. Send_Byte                                Sends one byte using SI pin to send and
    # D! K4 A1 s3 c2 d1 c( M! ~
  30.                                                 shift out 1-bit per clock rising edge$ G- D3 z, W% ~$ F4 I
  31. Get_Byte                                Receives one byte using SO pin to receive and shift : ^' I' l  R/ z1 T
  32.                                                 in 1-bit per clock falling edge& Q$ U/ {/ |8 W5 X! [
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    2 {+ e) W0 ?/ _2 x
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high" u. m5 h& E* t: |  J% V
  35. CE_Low                                        Clears Chip Enable of the serial flash to low0 w$ `$ P1 V0 G/ g
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    2 Y( c& u( W9 {
  37. Unhold                                        Unholds the serial flash
    5 j2 {+ g/ ]. O$ y9 x
  38. WP_Low                                        Clears WP pin to make serial flash write protected  C. c, b1 z, L+ O1 L  |
  39. UnWP                                        Disables write protection pin3 Z/ T! x7 _! m# n

  40. * N- s$ }! ~6 f) D1 V
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code& a/ I# W1 p. j+ E) S" B7 I
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    9 ?# n) n. g, D- a6 B4 [+ A
  43. software which should reflect your hardware interfaced.          
    " Y1 L+ d/ o7 {* h: b5 @

  44. 1 a/ j" ]% M. H7 V2 E" I/ q

  45. % b0 G: ]2 I% S/ w" W; k
  46. Device Operation Instruction functions:5 V: ]+ l- A, b5 \# v

  47.   X  @- V2 b$ t0 r5 V  d
  48. Functions                                    Function, y2 v( i! l1 h/ m6 i6 b, l
  49. ------------------------------------------------------------------9 V3 d% C1 Z2 A# V; d+ ~9 M' r
  50. Read_Status_Register        Reads the status register of the serial flash
    , c/ Q: `+ D: Y! z: I
  51. EWSR                                        Enables the Write Status Register
    " R; s1 p/ [8 e8 g5 G3 z! `6 {
  52. WRSR                                        Performs a write to the status register
    ! O9 E4 k$ o7 L# j" K
  53. WREN                                        Write enables the serial flash( L6 o% G5 A. a, h& P# U: a9 ]5 n
  54. WRDI                                        Write disables the serial flash& G% j" q* h* e+ w2 ?5 Z
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    0 c+ u) m( ?7 ^% r3 W; ?
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming& w0 W+ U5 d1 ]; T4 c0 |) r/ x/ ~
  57. Read_ID                                        Reads the manufacturer ID and device ID& w: J" _% R& t+ D9 p
  58. Jedec_ID_Read                        Reads the Jedec ID
    1 Y2 \1 n5 ~: a) \% s& d
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)4 J+ T8 L( M% A7 h* c& k" {9 |" \
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    $ D$ ^2 N4 I: I1 U) o
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    0 k4 k( @8 [) P. c% @$ G
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    : Z/ A* L. }. f
  63. Byte_Program                        Program one byte to the serial flash# _/ `: A" H2 M. j' a, G
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    ) Y- n8 D. ?. P
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    3 o; g4 |4 D6 @7 {; z
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY( m" u/ e) {3 q! L3 m
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    ) l, w$ a* o  S
  68. Chip_Erase                                Erases entire serial flash
    5 P5 K' E( E& Q1 M+ C. Z3 S
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    ) X- q# a; F* l/ ^, p2 V/ h0 I
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    1 V7 g2 E5 J2 X, }8 a
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash* h) R$ T( F3 @7 P' X7 j
  72. Wait_Busy                                Polls status register until busy bit is low
    - ^2 I( B+ I: P) u+ e/ X) x1 v, L
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming8 {1 v% l5 L$ T6 d2 z
  74. WREN_Check                                Checks to see if WEL is set
    4 T- T8 X# X2 A9 D; R
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    8 t: j- s6 l/ P* T
  76. + w9 Q4 x+ ]4 Z) y2 m+ R

  77. & k, E$ s  ^& |7 k: Q% o  H& N' f* L

  78. ; p. y% ~0 h5 x# I" i5 V2 q# w* U
  79.                                                                      - C* ^  _  }1 J# i7 L2 p
  80. "C" LANGUAGE DRIVERS
    4 c" Q2 `) }3 Z6 m  X

  81. 9 k8 F# b6 X7 ~$ E
  82. /********************************************************************/  h, f: f# }2 y  ~. X# K
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */3 i3 q' T) Q( R0 W
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    1 \: R) @  C- }: S( e
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */5 Q! |3 Z$ A  [# O/ N
  86. /*                                                                  */" O) n) {% k* k/ u, T$ B
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    5 O+ D" k$ }: `* q, n: K. j
  88. /*                                                                  */. e9 S& y( l( _; \
  89. /*                                                                                                                                        */
    & @4 Z3 O2 F" o6 T* C
  90. /********************************************************************/1 v+ h% m: H$ {8 K5 D0 ~3 v
  91. 5 v. e1 m3 G/ _. y& t* [0 i6 O
  92. #include <stdio.h>
    - B! r( w4 e. H; U+ M. \
  93. #include <stdlib.h>8 }  J# ^, ^  A
  94. , P; S) C0 D; J1 d
  95. /* Function Prototypes */
    $ i: S+ @6 T' ]3 Y4 g+ d

  96. 3 Z0 U# ?. y; `
  97. void init();
    ' |6 ^) O. v( R  V% H7 ^
  98. void Send_Byte(unsigned char out);% K% u4 c4 Y1 U- v
  99. unsigned char Get_Byte();
    ; a$ e. A& Z- k' V
  100. void Poll_SO();
    4 R0 t, |5 ^6 [
  101. void CE_High();7 J5 Q' f8 B# E
  102. void CE_Low();
    5 h% r" y' N0 W: p* U: W& k
  103. void Hold_Low();
    % g, G+ ?& G  h& B9 \
  104. void Unhold();
    $ {6 s: r: W/ G- u" @$ T3 P6 G
  105. void WP_Low();7 @4 X* R, X7 e- B8 ~( U
  106. void UnWP();* M7 e5 i/ W# [8 u8 k9 n' ?8 R
  107. unsigned char Read_Status_Register();
    ( v/ r+ g/ W7 v' T& b1 g1 e
  108. void EWSR();8 I* S1 e# V9 t/ k( s# `, g
  109. void WRSR(byte);
    6 b! ^4 u" [* v, T7 X$ U: C# M# |
  110. void WREN();
    ! ^. B  z9 i: ^' \0 j
  111. void WRDI();
    ' H7 L6 m& x4 H* u
  112. void EBSY();9 r1 w3 @. J' x+ h8 K1 R2 N* v( O
  113. void DBSY();' Q) _" x# K' _& ?; a$ P
  114. unsigned char Read_ID(ID_addr);
    3 _" J0 t% k9 E7 k- G
  115. unsigned long Jedec_ID_Read();
    * N$ {. p1 U$ T3 w# L
  116. unsigned char Read(unsigned long Dst);5 ?4 [8 o- B1 N" B
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);8 H/ d7 Q8 a0 t# m. V/ X; f
  118. unsigned char HighSpeed_Read(unsigned long Dst); 0 ]. G9 N9 e" I) V; I# T
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);  s# D! O7 @1 D3 l- ]( W7 y
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    % o! X8 Y# h- f  k; {
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);2 E- K0 U' L- w$ A0 Y+ }
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    4 H0 W  F! e& g7 Z9 x
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    6 B) u) M2 }4 b% Y- O
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);2 t- r5 R) C3 z  e4 ^" Q
  125. void Chip_Erase();
    , A& r& ^: G* t) d
  126. void Sector_Erase(unsigned long Dst);3 p* Q, v3 X1 y% N. a
  127. void Block_Erase_32K(unsigned long Dst);
    7 y# p  ~$ d& y* {8 }- b% s. n  ?1 J
  128. void Block_Erase_64K(unsigned long Dst);( m1 F/ ?. }5 x! Y
  129. void Wait_Busy();. n- {6 n6 N7 h1 |- n7 c
  130. void Wait_Busy_AAI();1 A6 F: r, z: y2 v# h- E
  131. void WREN_Check();
    % P9 a+ j  a1 m+ n) d8 S* s. _3 b
  132. void WREN_AAI_Check();
    3 N# u* c5 D% {( C' L3 h

  133. # X; R9 T0 y, x( l/ y
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    : Z4 t" J0 m; o5 P  C' K

  135. : x0 N& g  g2 ~2 R  k/ a
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    7 i# Q! {' A: z& l/ r% Y
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    " k7 |3 o% ?1 q

  138. , a( e' T# K8 C) r- ^. j# |; E
  139. /************************************************************************/
    " u0 f% \; t, Y
  140. /* PROCEDURE: init                                                                                                                */
    1 V6 m1 t$ C5 g% u# f) g2 M6 V
  141. /*                                                                                                                                                */. f+ Y1 Q/ K; G& E, }7 U3 G
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    ( B& e  i: d1 w6 E0 j
  143. /* setting up mode 0.                                                                                                        */! V6 s, g6 y+ O1 r9 Q2 e
  144. /*                                                                                                                                                */
    + I5 Z0 [) K; z
  145. /* Input:                                                                                                                                */* f0 c" S1 M0 e  i
  146. /*                None                                                                                                                        */
    : }4 V0 a; I; Y+ r" L
  147. /*                                                                                                                                                *// d6 P' Q; q( ~/ ^. R
  148. /* Output:                                                                                                                                */0 H/ ]) D6 ^2 N: u& O  p
  149. /*                SCK                                                                                                                                */' D4 s% B* L) d* R3 o4 E5 d2 S5 y
  150. /************************************************************************/
    % z$ _2 T* X* d9 k; F$ f
  151. void init()9 K' G! W3 U6 D; y3 H1 H' q
  152. {
    ! g" b. J: w: J$ L1 n0 U
  153.         SCK = 0;        /* set clock to low initial state */
    1 f2 l, N9 d: f' Y5 K* D
  154. }0 \% s4 v* x1 O  I# N( G

  155. 0 ~* N. l8 I8 D! J! f
  156. /************************************************************************/+ w( L$ S. ]/ N: S5 o9 L9 ?
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    9 D- ]& _/ c& i% a
  158. /*                                                                                                                                                */1 u8 ~& r/ T* n  e4 O" I' g7 V
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    + O* C0 {3 h+ O3 B/ j! F
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    , k- Q$ ^3 D5 f# z9 s7 J" ^$ ~" u, G
  161. /*                                                                                                                                                */
    ; z& C# |& a: ^; t. E' ~- x- b4 H
  162. /* Input:                                                                                                                                */
    0 ^( s' Y" M$ K% x7 T, s
  163. /*                out                                                                                                                                */
    7 J$ L- E( |: _  ^3 D
  164. /*                                                                                                                                                */
    $ T2 X4 q1 V& J7 ?
  165. /* Output:                                                                                                                                */
    8 }$ h2 O# P, ~  ^9 |! w* ]
  166. /*                SI                                                                                                                                */
    6 O/ s. u' p0 Z7 c" \! \
  167. /************************************************************************/
    1 S$ m. B+ R0 n. C" u; l
  168. void Send_Byte(unsigned char out)
    $ X+ H& @! r+ u& K! W
  169. {
    - Z% c9 D# G* J3 r
  170.        
    2 ~- U+ {" _3 S7 B7 Y- n
  171.         unsigned char i = 0;! [7 M( k9 E/ \6 p0 F$ I; ~
  172.         for (i = 0; i < 8; i++)
    9 |0 G2 B4 h0 f
  173.         {
    + F1 y1 f% ?- \/ x# N+ E5 |
  174.                
    + H) d$ I% d  y; ]
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */; K9 |' |! C0 M# G/ f. h5 i9 f
  176.                         SI = 1;
    8 L2 Z7 A& O4 c
  177.                 else9 p$ [/ `* k" T% p( w
  178.                         SI = 0;                                /* if not, set to low */9 w# {( t9 r* u' Z8 T' d! E7 J2 }
  179.                 SCK = 1;                                /* toggle clock high */
      i' ]3 A/ Z% N# n+ m. H' s
  180.                 out = (out << 1);                /* shift 1 place for next bit */5 g6 _% ]. K$ o6 b- u. y' _
  181.                 SCK = 0;                                /* toggle clock low */
    / M  w& b( s6 m* }" ]; @% i8 ]
  182.         }
    * G  m% e  b/ N1 ?# ?2 e) E9 b
  183. }) k  [$ t# D( T6 f; h" Z! F
  184. : @8 P7 v% c4 r3 g  @& [6 i& h  f
  185. /************************************************************************/8 o  V4 ^; C$ ^4 \, U( K! o
  186. /* PROCEDURE: Get_Byte                                                                                                        */* p6 W9 K: q% f
  187. /*                                                                                                                                                */
    , \1 b- L; m; ^
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */7 G9 E5 R- |) n& m' ?4 I! x) b
  189. /* edge on the SO pin(LSB 1st).                                                                                        */; ?, Y! b" T; u3 h
  190. /*                                                                                                                                                */( b9 s7 d. H: s7 Y: e
  191. /* Input:                                                                                                                                */
    ( z3 @5 |- C* J% S! C1 o$ y, u( `( c
  192. /*                SO                                                                                                                                */, y" n& J  G) U% A( s4 A" r- {' w
  193. /*                                                                                                                                                */# T+ K0 k$ H; u7 P* a/ _
  194. /* Output:                                                                                                                                */- e7 ?' D( S) U3 u/ f& L: n
  195. /*                None                                                                                                                        */
    ( ]# c0 R* f# u6 G! k
  196. /************************************************************************/( I! O) L! h) P- K" G
  197. unsigned char Get_Byte()
    + s9 `3 Y+ a! V& P! K# d  K
  198. {) \( K2 J3 h3 m, d# q
  199.         unsigned char i = 0, in = 0, temp = 0;
    4 J6 m7 t$ D, n
  200.         for (i = 0; i < 8; i++)% L; S5 o5 ^6 k" P1 D3 }
  201.         {
    " K4 @2 ]+ s0 g' S$ X
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */* G: ]5 k- d4 ?+ e) b4 _) q
  203.                 temp = SO;                        /* save input */3 U9 L5 D# c/ R- j
  204.                 SCK = 1;                        /* toggle clock high */
    0 s2 G& [( r) A
  205.                 if (temp == 1)                        /* check to see if bit is high */2 Q0 H3 b- y1 O& j4 p
  206.                         in = in | 0x01;                /* if high, make bit high */
    6 j! X: a( T/ s& K0 D

  207. - W4 D+ S% ]; s
  208.                 SCK = 0;                        /* toggle clock low */  q4 i" H# ]; L4 E  J- |3 X9 m( Y" G* ~
  209.   R/ @9 B$ E2 j( j
  210.         }
    ' W5 T7 P& O$ k, e
  211.         return in;
    % v1 K3 i7 B) r8 }) T; F$ U
  212. }
    ! E1 O* [+ w* C

  213. 8 [& p7 [  e0 M! |! r8 ~* q1 f4 o
  214. /************************************************************************/3 ^* a4 s8 L* z2 [( f) p* ^/ w6 t
  215. /* PROCEDURE: Poll_SO                                                                                                        */3 Q9 t. w4 Z; y. x6 {
  216. /*                                                                                                                                                */' z' F( ]7 v8 `# z  D  ]# H! a
  217. /* This procedure polls for the SO line during AAI programming                  */4 s8 c8 }! x& a5 C. `% f: Z: X" ~
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    4 W' ]% A) i: ~+ I& _  F
  219. /* is completed                                                                                                                        */
    # v4 n+ U# {6 H1 S5 E
  220. /*                                                                                                                                                */
    ' F, x/ y; `' o1 w
  221. /* Input:                                                                                                                                */
    % s+ E* e# J1 Z5 V7 V
  222. /*                SO                                                                                                                                */7 w6 _" v, D. D$ s% S: H
  223. /*                                                                                                                                                */7 x4 O  \7 G; |! z
  224. /* Output:                                                                                                                                */# r/ @" v% o1 i7 W, `- `5 ~/ [# }
  225. /*                None                                                                                                                        */
    % ~, J7 i! F( I4 F1 {
  226. /************************************************************************/
    + ^: W9 I! U, h3 i2 I
  227. void Poll_SO()
    # X9 G$ v& X  X
  228. {7 ^% d" c3 c- G) v1 }
  229.         unsigned char temp = 0;2 Y" U0 ^" J$ N! q: m3 `; z) d
  230.         CE_Low();
    & L6 M+ B8 U( C+ u% \
  231.     while (temp == 0x00)        /* waste time until not busy */* x$ I/ j( B$ N% ]
  232.                 temp = SO;# z! |: ?" C3 e/ ?
  233.         CE_High();  M4 h1 {% i. F. ]
  234. }
    9 _7 d# b+ b3 S9 e  i$ ~0 n
  235. # Y. O( F. Y/ _6 v
  236. /************************************************************************/
    " \3 l  |5 x) Y6 s7 M+ e
  237. /* PROCEDURE: CE_High                                                                                                        */
    , k, x, L5 t  U4 X3 \& ?! t! M
  238. /*                                                                                                                                                */3 R) G- e& G. ^3 W5 A$ S2 Z3 @, M* o4 b
  239. /* This procedure set CE = High.                                                                                */
    ) f5 s! g# z& J6 k6 I: n
  240. /*                                                                                                                                                */
    8 ~7 L& w! J7 x* l1 p  x8 O
  241. /* Input:                                                                                                                                */
    - \. \3 C# d2 x* @( B! e3 u
  242. /*                None                                                                                                                        */- R* y+ U- v6 ]7 L
  243. /*                                                                                                                                                */
    * \( F3 x" Q+ V. r/ A; P1 \
  244. /* Output:                                                                                                                                */
    & h4 d5 p+ p8 W5 N# G5 O: [
  245. /*                CE                                                                                                                                */
    $ M+ D0 _! Z6 k
  246. /*                                                                                                                                                */
    7 [9 f8 i) V+ P
  247. /************************************************************************/9 g# `* V6 ^2 @' C
  248. void CE_High()
    : @' Z2 ]: G6 t7 t3 x0 \! ~( ^+ d
  249. {
    ( U! B9 G9 A& F& l
  250.         CE = 1;                                /* set CE high */  W, A7 p& I8 L
  251. }
    9 D7 e& Q# s: ~6 y7 [4 J- {

  252. ' X6 W, j! B* Q
  253. /************************************************************************/, u) t, }! G, [
  254. /* PROCEDURE: CE_Low                                                                                                        */
    ; A1 d6 c0 P; {- O" ^
  255. /*                                                                                                                                                */" j: o8 {  B- z, d
  256. /* This procedure drives the CE of the device to low.                                          */
    " k, a- G' t8 V8 S# s6 j
  257. /*                                                                                                                                                */$ @: ~8 D! W* J5 g
  258. /* Input:                                                                                                                                */( v: F) F' U9 h
  259. /*                None                                                                                                                        */
    5 c" e* q$ L8 E. s. H+ y5 T% ~0 v# E
  260. /*                                                                                                                                                */
    , T9 {1 s; q) l% E
  261. /* Output:                                                                                                                                */
      M. x. p' @; i0 P/ d: k' Y- w
  262. /*                CE                                                                                                                                */
    , h: O& M; D2 Q
  263. /*                                                                                                                                                */
    " v: u+ v$ T* U0 S0 A  T  |
  264. /************************************************************************/
    % A0 E$ ?. G2 |! ]' o+ p' e8 j7 Y. v
  265. void CE_Low() ) n  I3 s8 m. t6 G2 ?
  266. {       
    , d/ [. _, V9 H. g0 e/ a
  267.         CE = 0;                                /* clear CE low */
    : s/ k4 ?$ U; {$ @
  268. }: F( u' H! @7 U1 O) v; Q* u
  269. 2 z5 [: J$ N: `5 m
  270. /************************************************************************/: f+ r: i2 h  j# _$ a4 o5 l7 {
  271. /* PROCEDURE: Hold()                                                                                                        */
    ) O# G/ d/ ^1 K) R' P
  272. /*                                                                                                                                                */
    4 ?+ F8 F/ W$ p  E
  273. /* This procedure clears the Hold pin to low.                                                        */
    , Y# l  e, i/ a9 H9 o, ]" j: X
  274. /*                                                                                                                                                */
    + s  M  x' ?& K/ X, K& a: ?
  275. /* Input:                                                                                                                                */
    9 r/ W: x) [4 ?' i- {  m3 E8 j
  276. /*                None                                                                                                                        */
    ; q+ w, [+ m9 i( n
  277. /*                                                                                                                                                */0 c4 q1 \' K" ?# A- u8 v% b/ _
  278. /* Output:                                                                                                                                */
    + \( Y$ r9 x: i4 \0 a% T1 E
  279. /*                Hold                                                                                                                        */
    ( V- o& t# y! s$ Y
  280. /************************************************************************/
    ; \  G' q. }0 W2 ]6 e
  281. void Hold_Low()
    * x+ O: r: C: U) }: q
  282. {
    8 m" w( L7 ^: X4 h9 ^
  283.         Hold = 0;                        /* clear Hold pin *// D9 A$ z- F8 h, ^; F! {) O
  284. }
    : Q, S+ c- g$ M7 \6 ~

  285. ! t$ `! W0 A; H- h# a  [, l; ?
  286. /************************************************************************/
    . X8 B2 K7 b# d$ y; ~$ P" S
  287. /* PROCEDURE: Unhold()                                                                                                        */
    , j6 z+ o, s! w/ f4 a- h
  288. /*                                                                                                                                                */
    0 @5 c/ k! k. b
  289. /* This procedure sets the Hold pin to high.                                                        *// b. ~: E& Z/ q0 a0 o% G6 Y
  290. /*                                                                                                                                                */
    ' v) y% y$ }% I- U
  291. /* Input:                                                                                                                                */& w- g8 ~. S9 K; ~) c5 g8 D) q
  292. /*                None                                                                                                                        */
    : x! Z5 ?% L* d2 |8 C. s2 Q
  293. /*                                                                                                                                                */- n& a, r% d3 j" @
  294. /* Output:                                                                                                                                */6 l* c0 a4 _$ ~4 n. m
  295. /*                Hold                                                                                                                        */
    & H  B/ {  g: c# A: `
  296. /************************************************************************/
    7 z" ~$ c' f# L0 ?; ^
  297. void Unhold()
    * r6 w, K" _2 ?9 k5 Q
  298. {
    3 a; ~9 m' \. ?- X" ]/ ^) N4 @
  299.         Hold = 1;                        /* set Hold pin */
    * I& h# K- D4 K2 w1 J; Y
  300. }3 z; d; L) W1 ?7 p* ]+ L
  301. 0 [2 s& f+ f8 C$ F1 X
  302. /************************************************************************/
    3 h& K; l2 e9 q1 }3 |
  303. /* PROCEDURE: WP()                                                                                                                */
    8 Z) t8 ~! a- v: K  Y7 K  W2 Q6 }
  304. /*                                                                                                                                                */
    ! _. J7 O1 o0 W/ V' N5 z' [
  305. /* This procedure clears the WP pin to low.                                                                */
    1 v. }# Z( ?  s. l8 j
  306. /*                                                                                                                                                */% K8 {8 b$ C' e* X/ u8 R2 O
  307. /* Input:                                                                                                                                */
    3 V4 g( h. u. @# ]+ }% z
  308. /*                None                                                                                                                        */
    " h  n& I1 l+ P) G$ s/ S* h
  309. /*                                                                                                                                                */
      g7 \' L, W5 [
  310. /* Output:                                                                                                                                */
    ( c  X3 ]& U! ^9 t4 {
  311. /*                WP                                                                                                                                */
    - A1 j# ~0 ?/ d& I; |$ c
  312. /************************************************************************/7 j" _) }$ t4 ^' d. Q4 B$ P) E
  313. void WP_Low()
    3 p* h2 C/ c$ l( Q- P' f
  314. {! A9 g2 f4 r3 C* @& r" k; c
  315.         WP = 0;                                /* clear WP pin */
    ) k; r- L( t/ O* c7 b& B
  316. }
    8 @5 Q+ v. U  n3 `" g" m6 e
  317. 6 T8 O' H, c9 @$ I2 ~4 o
  318. /************************************************************************/
    ! I* H" G1 K8 j8 c+ ^) E3 H% y4 x
  319. /* PROCEDURE: UnWP()                                                                                                        */
      }' ?8 e, a+ U8 l
  320. /*                                                                                                                                                */1 D0 y" E# u1 e$ j
  321. /* This procedure sets the WP pin to high.                                                                */* @1 W- A. w0 r8 P, F
  322. /*                                                                                                                                                */- o5 {2 g1 s4 H
  323. /* Input:                                                                                                                                */
      a8 I8 F/ j5 D" F, a
  324. /*                None                                                                                                                        */
    5 F- K2 |1 {5 B2 }! S' }+ `1 g
  325. /*                                                                                                                                                */
    ; G+ ^7 c+ I' |/ |0 K
  326. /* Output:                                                                                                                                */0 o- I1 t+ Y# n3 B
  327. /*                WP                                                                                                                                */
    ! [; D  c) U0 N; z) e
  328. /************************************************************************/; }2 u) U) T" L' ?8 s" i& M. W
  329. void UnWP()
    4 O$ c' o4 Z& r  z- Z
  330. {
    & ]4 z7 R" ]$ W1 _2 n" }
  331.         WP = 1;                                /* set WP pin */
    # w9 J/ n, O9 M# L) R& T
  332. }
    9 `4 f- Q/ j7 K
  333. & e4 U# y$ F' H) d/ `! I$ K' w
  334. /************************************************************************/
    . j; u( P0 n0 y; [8 D9 J
  335. /* PROCEDURE: Read_Status_Register                                                                                */0 v. r( T# T; i9 u
  336. /*                                                                                                                                                */" J% X( p! |0 f' v
  337. /* This procedure read the status register and returns the byte.                */" F: Z8 c/ S' c7 V8 p7 N+ C$ J8 l
  338. /*                                                                                                                                                */
    5 c- d% f! F7 U$ w
  339. /* Input:                                                                                                                                */
    ! X$ ~' w& H) O* t& d
  340. /*                None                                                                                                                        */
      A9 d/ o# s/ r3 I2 A% F4 a% ^
  341. /*                                                                                                                                                */: p* q' D4 C# L9 D- }9 j
  342. /* Returns:                                                                                                                                */9 w: T" U/ l3 V, Z+ H5 A" i: y5 G
  343. /*                byte                                                                                                                        */1 W2 l. u# Q2 f0 V; w
  344. /************************************************************************/
    $ p# V! k8 r/ }- h! i$ e0 \* o7 C
  345. unsigned char Read_Status_Register()
    ) W# L" F' k+ l# E
  346. {
    8 e0 [# [/ {: I  v) J# ~5 B. V
  347.         unsigned char byte = 0;* s  a: F6 k- q. u/ x  v5 h5 V
  348.         CE_Low();                                /* enable device */0 h+ C# b2 z( t4 T2 i3 \) X  V1 T
  349.         Send_Byte(0x05);                /* send RDSR command */
    9 v8 G2 g/ T# w, {% w: v
  350.         byte = Get_Byte();                /* receive byte */- o7 b: d3 s; I& g& _/ A0 L
  351.         CE_High();                                /* disable device */4 L* N: ~1 {1 _4 r
  352.         return byte;
    + I& W2 V& `/ Y8 n' r* B! [
  353. }% P3 A' e: x1 s
  354. % ^2 a' w1 g  ^7 r9 p
  355. /************************************************************************/
    : Z$ K- g$ W' t  Q5 `
  356. /* PROCEDURE: EWSR                                                                                                                */
    # W% z# d! k; z4 N3 q
  357. /*                                                                                                                                                */4 m2 _" ]5 N+ k+ D3 J
  358. /* This procedure Enables Write Status Register.                                                  */
    & `# w0 R0 L1 k
  359. /*                                                                                                                                                */
    0 O1 E) [+ _% f8 ]7 d3 M
  360. /* Input:                                                                                                                                */: ~# X6 u; D+ s! m% w' O
  361. /*                None                                                                                                                        */: ^0 y% Q- v6 K" G4 U
  362. /*                                                                                                                                                */4 g6 e; p( V: K1 Q
  363. /* Returns:                                                                                                                                */! u0 I& l4 |, e' h5 O
  364. /*                Nothing                                                                                                                        */6 D( q: y. _5 t, l) Z
  365. /************************************************************************/
    7 i+ O: R- k& O# q8 t  Z% [! A" z
  366. void EWSR()7 U3 d, o/ M6 r2 z
  367. {
      @/ Q0 w; I, b! h, y# s
  368.         CE_Low();                                /* enable device */
    $ F9 d4 O0 T% Z' E; n' ?" m' K9 |
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    & I% D$ v1 k$ V3 s' T* C' o
  370.         CE_High();                                /* disable device */
    ; ]0 C. m+ f0 C* }
  371. }
    - r7 [% q/ h+ u) ~& z2 {

  372. # X% k8 c& {3 q0 n
  373. /************************************************************************/
    0 D/ l0 ?+ H$ v: O; t: A( N
  374. /* PROCEDURE: WRSR                                                                                                                */
    $ X: p0 n, W+ l6 |& c1 ^7 E! `
  375. /*                                                                                                                                                */, t7 v7 _  |+ `
  376. /* This procedure writes a byte to the Status Register.                                        */
    8 g) k# o# e9 t+ o
  377. /*                                                                                                                                                */
    7 _0 d6 A2 p6 e4 G- P( f# K
  378. /* Input:                                                                                                                                */% i4 F) o/ ?( |8 b
  379. /*                byte                                                                                                                        */( A  Q4 P  i+ z; q
  380. /*                                                                                                                                                */
    9 M  f- V( \) `, c
  381. /* Returns:                                                                                                                                */" R5 I6 s7 [; R, y
  382. /*                Nothing                                                                                                                        */" x& _% e) w1 W0 z0 \& [  V. S
  383. /************************************************************************/$ v( \3 U6 z' @( Z+ L
  384. void WRSR(byte)2 a$ p+ Y2 t, S
  385. {4 E9 _/ F8 a0 x. O% J
  386.         CE_Low();                                /* enable device */* k& U: i/ [: K- l2 v# U% c* |8 J
  387.         Send_Byte(0x01);                /* select write to status register */
    " E9 M7 z0 n! @8 ^
  388.         Send_Byte(byte);                /* data that will change the status of BPx 8 p1 F( I# B3 @5 y6 e2 W
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */1 Y  j& C0 N* J- o0 B8 `
  390.         CE_High();                                /* disable the device */  s( P9 n, [; A3 H% r
  391. }
    8 F! F: A+ T% W: t

  392. 0 U9 u7 N; H6 c2 d) y
  393. /************************************************************************/
    / ]- X5 [; w6 k& p
  394. /* PROCEDURE: WREN                                                                                                                */* f$ c6 m! @* F% ~
  395. /*                                                                                                                                                */
    % G; G# l3 Z( L; q- f1 Y6 z$ ~
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    ' y% ]0 Q! ~( c. D! l
  397. /* to Enables Write Status Register.                                                                        */9 T9 q! J/ k  ?1 s( p9 p) P
  398. /*                                                                                                                                                */! ^9 y& r5 z; U: F/ c6 p) Y/ X
  399. /* Input:                                                                                                                                */9 G: k  D  }! E* W
  400. /*                None                                                                                                                        */4 g1 f5 _4 o8 M6 v" Q" Z8 v+ v
  401. /*                                                                                                                                                */
    . I  P  e' D: o; t; h
  402. /* Returns:                                                                                                                                */( F1 H  @1 `' b7 N. w
  403. /*                Nothing                                                                                                                        */
    % ], h- ^2 k/ X! h& ~' ~
  404. /************************************************************************/
    1 F# k" g- n) F/ ~# y6 e$ U, Z+ o
  405. void WREN()& B( V2 `$ c5 J; G8 v
  406. {
    4 q3 |, V8 f4 ~( |( Q
  407.         CE_Low();                                /* enable device */& K* `  t! Y' O7 }
  408.         Send_Byte(0x06);                /* send WREN command */+ \  F4 Z+ P- q. m
  409.         CE_High();                                /* disable device */
    : y/ _# B2 k; _* v# q7 T
  410. }
    % g) s% B% }% T$ g! {5 {

  411. # d5 h# B% J+ C4 ~5 R
  412. /************************************************************************/  o6 g, N2 K$ s- L6 }
  413. /* PROCEDURE: WRDI                                                                                                                */
    4 z5 |# X, Y; `5 o+ F1 L/ t3 b/ h6 R- A
  414. /*                                                                                                                                                */. e$ S0 M9 l' C: q. N* s
  415. /* This procedure disables the Write Enable Latch.                                                */
    & k: R. K  b/ L# z
  416. /*                                                                                                                                                */& r/ d# W. f& ^/ [5 Q
  417. /* Input:                                                                                                                                */
    2 a# d4 h# ]8 n/ k; R
  418. /*                None                                                                                                                        */; f/ f! T1 B) m; L( B
  419. /*                                                                                                                                                */7 X8 F# n: @' g7 g: I. l7 F
  420. /* Returns:                                                                                                                                */- A; R: f% x7 J, B1 {0 u
  421. /*                Nothing                                                                                                                        */: ?! D- Y5 R- _+ r- M
  422. /************************************************************************/
    4 S! \) g- A% p5 a" H5 k1 F1 C
  423. void WRDI()
    9 X' s+ \2 R, ^! N3 z  n2 O
  424. {
    # j# Y1 a' m: X# G; I  w
  425.         CE_Low();                                /* enable device */
    2 w! H- {6 B5 u+ _' L7 p. e
  426.         Send_Byte(0x04);                /* send WRDI command */7 r+ @" o+ d; U2 y9 W8 S
  427.         CE_High();                                /* disable device */6 c9 N# N8 P: ?' r& }2 p2 ~- Q
  428. }
    ( w! q  X9 K+ b/ B! s: [% |
  429. * p& P) Z4 z7 I- P' A
  430. /************************************************************************/) l& [* x# u  R3 [! O
  431. /* PROCEDURE: EBSY                                                                                                                */
    ; K5 }" M  @7 |7 v; \1 o
  432. /*                                                                                                                                                */
    & l: P- u4 o+ _
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */0 f0 O9 i8 H, m" P. O: P: B
  434. /* programming.                                                                                                                        */1 q5 \- Q4 D# i0 n
  435. /*                                                                                                                                                */' J# a( a, P4 K9 B4 h
  436. /* Input:                                                                                                                                */
    $ s. H) N! Z2 x( n4 D2 y3 B& K* H
  437. /*                None                                                                                                                        */
    1 E( [: T+ k: \2 G+ N. A; n
  438. /*                                                                                                                                                */' q( C8 Q0 U# `
  439. /* Returns:                                                                                                                                */
    - |4 r/ l# x' y0 u; v' C5 L
  440. /*                Nothing                                                                                                                        */8 A- K' T% P0 T2 |2 a
  441. /************************************************************************/
    ; s4 ^! N/ Q: N" B8 N4 }5 Z
  442. void EBSY()
      x( s+ i  |6 ]- U% K% K$ L8 ]- d$ Z2 F( }
  443. {
    8 T/ G$ a7 o' D
  444.         CE_Low();                                /* enable device */
    2 H4 @7 o# i: A" x& h0 L( w0 ?
  445.         Send_Byte(0x70);                /* send EBSY command */
    - U4 Y9 R, x, Z' q0 s
  446.         CE_High();                                /* disable device */' p* C* V, _& m* K+ `
  447. }
    : R! J& {! ]6 x1 y5 g$ n& E

  448. : Q% |* {5 C/ l; q
  449. /************************************************************************/
    $ R$ U/ s0 }5 V
  450. /* PROCEDURE: DBSY                                                                                                                */
    4 p( `) c7 h# c' t1 ~
  451. /*                                                                                                                                                */) |# o& y  P6 @8 E
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    0 I  g6 }4 K4 Z9 X! O3 b; `
  453. /* programming.                                                                                                                        */9 G+ L9 [1 }9 W4 @. z
  454. /*                                                                                                                                                */
    * {  a6 e4 k9 ~3 R# g3 Z
  455. /* Input:                                                                                                                                */- C' S% V- h2 n9 N4 x- D
  456. /*                None                                                                                                                        */
    7 m! C# S' D2 h0 I) c
  457. /*                                                                                                                                                */3 i# N  |/ a4 F4 Z1 @
  458. /* Returns:                                                                                                                                */
    8 K2 W6 C1 i7 ~8 G
  459. /*                Nothing                                                                                                                        */; t# W& p# A( ^" V9 \: r
  460. /************************************************************************/9 J1 o) J' P; Z: I' w, C
  461. void DBSY()6 T  m7 n! \5 Y$ L4 c) G0 [. c0 s
  462. {/ k) g( }9 g( _9 M. J4 [
  463.         CE_Low();                                /* enable device */2 [8 `4 g1 n% @0 d5 C) e
  464.         Send_Byte(0x80);                /* send DBSY command */; ]9 c. P% E6 j' f
  465.         CE_High();                                /* disable device */; P  h6 p+ c% N& g
  466. }
    / i( O8 D! a0 f

  467. 5 S$ y; g! M4 w& q" m/ n" B
  468. /************************************************************************/1 }  G) r3 _( O
  469. /* PROCEDURE: Read_ID                                                                                                        */
    ; V: x3 N: t* }
  470. /*                                                                                                                                                */, e/ \7 B4 ~+ T1 q# D, h% {7 X
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    ) I9 m; d+ J. L- E3 _
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    2 W' \6 C" b# _
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    ( _/ n. h, E( Y5 t4 m* W) I
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    ; R2 m+ d) K. U( S9 Q9 s6 C, V* N
  475. /* first.  Please see the product datasheet for details.  Returns ID in */$ [( t. r; l& p  K' c/ C
  476. /* variable byte.                                                                                                                */4 s: b& O6 n' i
  477. /*                                                                                                                                                */: v  S- K) s  M. V6 R/ r$ {
  478. /* Input:                                                                                                                                */
    * q4 z" L4 O4 U) ~# }+ ]$ _
  479. /*                ID_addr                                                                                                                        */" p3 p$ x6 q" C
  480. /*                                                                                                                                                */! ]" |7 C( ]- P; V  n: F
  481. /* Returns:                                                                                                                                */0 q+ t' T( e3 t. A
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    & C: |6 }8 W& G, w* x, h2 V* ~( |
  483. /*                                                                                                                                                */
    + n* p6 O  ]" t  }
  484. /************************************************************************/( a3 u) |/ ?# O' z! H( H
  485. unsigned char Read_ID(ID_addr)
    # c' n# U% ^4 t5 C3 v
  486. {. c2 X7 l) U3 ], E3 g* V: G( O! G
  487.         unsigned char byte;" }. U6 {$ F! O. V; G+ Y
  488.         CE_Low();                                /* enable device */
    1 }: a8 j4 i0 {' L) }# H9 |* X) y0 ]. B
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) *// `: j# h' l; \: V5 s! e
  490.     Send_Byte(0x00);                /* send address */
    # W3 C' G0 U& P$ z5 X
  491.         Send_Byte(0x00);                /* send address */. }  b" g0 q% \! U% J/ W1 a. I  @
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    ' l( R' k4 ~8 ^9 n
  493.         byte = Get_Byte();                /* receive byte */
    ; \+ M( K5 o- K$ Y+ j
  494.         CE_High();                                /* disable device */
    & W! n. h' x# @0 S8 E* \6 i
  495.         return byte;
    2 Q1 s+ L3 e& p$ g! W2 M. k2 D
  496. }
    + X' ^/ [+ e6 y, P
  497. . E" ?9 z. g. G6 C. ~3 Y
  498. /************************************************************************/
    # ^& D. V1 R: H1 [6 |/ l
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    ; u; x8 U- I1 x: Q
  500. /*                                                                                                                                                */
    ; \7 L& f. N* i! p1 k2 O) J: x
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    ; p5 X5 N3 s1 W5 Y7 W
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    ; h: }9 K/ ]& a$ L! d
  503. /* Please see the product datasheet for details.                                                  */0 V% D; u) |0 J! x
  504. /*                                                                                                                                                */  |2 b+ I9 R/ T9 u1 _
  505. /* Input:                                                                                                                                */* v# `. W- c" e- {$ Y8 m2 T4 C$ m! C
  506. /*                None                                                                                                                        */
    , L- a; _- u( j/ t
  507. /*                                                                                                                                                */) D5 b: A! p; j2 q% j5 T
  508. /* Returns:                                                                                                                                */
    $ @8 A2 Q7 G' Z" A
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    . E+ D: a. [! G% a2 h7 T! W" b
  510. /*                 and Device ID (8Eh)                                                                                        */" m! R( c( ?+ p# w: y
  511. /*                                                                                                                                                */
    # d1 B- O9 R9 p5 `9 B; `
  512. /************************************************************************/4 x/ s4 @/ I* d$ y3 ]
  513. unsigned long Jedec_ID_Read() 8 d+ a- `/ B; a+ p4 A0 C
  514. {
    1 Q, Q6 O! _9 M
  515.         unsigned long temp;1 y$ @1 _. B' n) ^8 s
  516.        
    6 a- j% ]" t* K% j
  517.         temp = 0;
    ( i/ z0 V- H; X/ {0 }
  518. 2 y! `2 {" v- ~
  519.         CE_Low();                                        /* enable device */) R+ l9 d6 q! o& R+ U7 H+ i
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */! q, h& {0 p' P
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    ! H/ z2 y5 H1 K: {
  522.         temp = (temp | Get_Byte()) << 8;       
    9 a5 }- ]! P" {5 Q+ S
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */- J' D- K0 ?7 c0 O" E
  524.         CE_High();                                                        /* disable device */
    ) S8 o& ^% s! B9 c+ A3 h

  525. 7 q3 z1 ?' b6 Y8 C- N+ a
  526.         return temp;
      B- h. \$ X! r. D$ V0 ^% T
  527. }
    : R4 D7 u* a. \/ }- r& O
  528. ' R' K$ b$ e0 F* x
  529. /************************************************************************/# [+ a. m# l& o) F$ ]" h/ r3 O, s
  530. /* PROCEDURE:        Read                                                                                                        */
    4 }; Y% G! j2 i2 [
  531. /*                                                                                                                                                */                ! ]" t- G% r( H! S4 H+ b& K
  532. /* This procedure reads one address of the device.  It will return the         */
    ! r6 Q' I6 m$ e9 f# s7 o
  533. /* byte read in variable byte.                                                                                        */
    1 v" h8 L1 h/ s6 @  {
  534. /*                                                                                                                                                */" g5 F4 M  G0 f5 j: ^- P" c
  535. /*                                                                                                                                                */
    $ |6 G, X  t  f, }: x. @  G7 d: A
  536. /*                                                                                                                                                */  w# q. I+ K7 ~1 Z
  537. /* Input:                                                                                                                                */' m: D" c9 A1 o- p
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */, e) b  V. V2 W5 K% f3 y
  539. /*                                                                                                                                      */
    4 M$ u& t: `) y9 n4 L0 w. `9 x
  540. /*                                                                                                                                                */+ r5 A2 p; q$ e9 `5 Z: D: U
  541. /* Returns:                                                                                                                                */7 i2 U, P9 D# P4 E- b8 r
  542. /*                byte                                                                                                                        */% w) `. l7 ?6 g  J, D' n. T8 j
  543. /*                                                                                                                                                */$ V& O) Z$ ~1 C9 \4 o
  544. /************************************************************************/! V1 \0 `- C0 [
  545. unsigned char Read(unsigned long Dst) 5 j2 I% ?, ^" B2 s+ q: S
  546. {
    8 l7 K2 L, [, I
  547.         unsigned char byte = 0;        & h* V7 E& Z9 _0 M! X
  548. : f" d9 t0 B1 v/ X9 @- B; A8 p
  549.         CE_Low();                                /* enable device */
      [) q9 v: i2 S2 s5 Z
  550.         Send_Byte(0x03);                 /* read command */
    % p- E' ~0 b2 ?  ?2 d- d4 p
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    7 ^9 M! V7 y1 b- h* D. n( z2 x
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));$ O3 k) C) P) H
  553.         Send_Byte(Dst & 0xFF);& L; b8 f2 \0 U  o+ ^, s6 ~. e
  554.         byte = Get_Byte();
    ) n$ |/ T% e) E5 l" s) V
  555.         CE_High();                                /* disable device */
    8 N( p2 u* O1 c1 g) _" @6 y
  556.         return byte;                        /* return one byte read */
      k. f0 c8 R7 j. R* B6 D5 N6 a$ I3 |
  557. }. @, Q7 @. o; T9 W  z+ ]1 z

  558. 8 R4 R9 m  |- K) }- [6 i3 |% K5 v
  559. /************************************************************************/2 W6 ^$ [) S0 n5 e8 V
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    / |- u' @  h3 J& g5 i2 o8 o( U* c
  561. /*                                                                                                                                                */                # A* z/ D) e+ ]9 k
  562. /* This procedure reads multiple addresses of the device and stores                */- n# P# E- _' E, L- r
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    # j" H6 E: x3 X8 R% Y
  564. /*                                                                                                                                                */
    + }" E3 `2 C! _5 L* C# J
  565. /* Input:                                                                                                                                */
    % U- I+ T! T# o0 t: R; P# F
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    # c" F# b5 \& q8 s
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */* G$ t! n3 D0 m! W* E
  568. /*                                                                                                                                                */4 m$ w6 @5 X8 o7 @+ R! i8 W: u
  569. /* Returns:                                                                                                                                */
    $ b$ L  j' F# v; ~& C
  570. /*                Nothing                                                                                                                        */
    ( o3 m4 I) Y: }- a, U0 L' A) _
  571. /*                                                                                                                                                */
    6 o$ [. s; C4 ~' |% J
  572. /************************************************************************/
    8 \# }/ o3 ], O  _
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    5 S+ U3 }* A" r) v7 h5 I
  574. {
    % Q2 K/ r' x7 `$ \
  575.         unsigned long i = 0;0 K' c  Y1 H6 ~6 c( G" @3 F0 ^- \
  576.         CE_Low();                                        /* enable device */$ y2 e4 r- R9 L+ ~+ f8 o+ w
  577.         Send_Byte(0x03);                         /* read command */! g/ ?1 O7 E5 v% q2 _+ T& T. u
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */0 g2 \7 G9 _) P0 G) ]' k6 a5 z/ f
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));; P6 O" i  p8 ^) v/ H; h
  580.         Send_Byte(Dst & 0xFF);* h. B3 m$ v4 P4 t9 W: V8 p: M
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */$ u5 W4 P! t: {6 p, ^
  582.         {
    6 W/ |8 F" G' t+ f- I2 o
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */( m, G0 K3 q: N& y
  584.         }$ W- P5 `, j# y% @3 m, O
  585.         CE_High();                                        /* disable device */  A* w/ s$ k) f# J) R& g# Q+ m( {
  586. " o5 h( s* L, o  J% [5 k
  587. }% ]- S9 P) B2 D- ?' g  W
  588. 7 d- i2 W8 }; k) |' j  {, M. _
  589. /************************************************************************/
    6 [3 i, N" W( H  a' b, Z% s
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */+ t! _! _- e" l1 W: N: P
  591. /*                                                                                                                                                */                + w1 A, W- r* s3 d0 Y, N
  592. /* This procedure reads one address of the device.  It will return the         */% w" N; H1 i% }) A( l" N
  593. /* byte read in variable byte.                                                                                        */7 q/ m% X- V+ h/ k  R# a/ I
  594. /*                                                                                                                                                */
    : C7 D9 M( X! [
  595. /*                                                                                                                                                */
    % k! A2 p1 f) o  {
  596. /*                                                                                                                                                */
    ; n. T# X9 b4 m5 X" a- t
  597. /* Input:                                                                                                                                */
    - |8 O) ^+ D. w& X
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    8 R- t; u5 z3 I8 p1 @" b3 _
  599. /*                                                                                                                                      */
    8 G) ?- x7 j: g% w: y# \
  600. /*                                                                                                                                                */) q  T1 e6 C+ N9 w! @
  601. /* Returns:                                                                                                                                */7 U' c3 R* w) M  @" ?
  602. /*                byte                                                                                                                        */
    6 i2 J( n9 W5 J4 M: w
  603. /*                                                                                                                                                */* [1 w! d! @  p4 u  _; i+ d
  604. /************************************************************************/$ ~/ A9 n) d* y9 C4 Q* o6 x
  605. unsigned char HighSpeed_Read(unsigned long Dst) 5 d. D. r, D, x: m6 N0 _5 n
  606. {7 t: ?9 e. b* t' h
  607.         unsigned char byte = 0;       
      y# ]* c" P* n1 h/ N

  608. 6 O. g- A: C. f! x) c
  609.         CE_Low();                                /* enable device */. l: b/ v" G, Y, t
  610.         Send_Byte(0x0B);                 /* read command */; v2 F* j0 h/ ?8 ~: G, n' E
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    2 h: {9 h% ?6 K- Q. B
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));& f$ N, y" |6 N( x- |! E, e
  613.         Send_Byte(Dst & 0xFF);
    % q2 Y* j$ J  l% R1 [
  614.         Send_Byte(0xFF);                /*dummy byte*/
    3 G+ S! g4 r1 i
  615.         byte = Get_Byte();
    7 G7 ?8 y5 y1 D; n9 ~* |
  616.         CE_High();                                /* disable device */3 ?0 E$ v5 E  |& s
  617.         return byte;                        /* return one byte read */. n) _! H+ P; |- g) X1 v; |
  618. }: Y: H" D; ^. M' e- f

  619. 6 r* W* y- I5 ]  H* s  y
  620. /************************************************************************/7 [- u# L4 |2 H* Z$ X" O
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */7 [; n6 ^3 y$ |1 g' F2 D2 D: t/ J; A
  622. /*                                                                                                                                                */                $ E# W; t  [( L9 x1 X: y
  623. /* This procedure reads multiple addresses of the device and stores                */
    ( f- ?, R3 x! Z" o% d
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/0 y1 C& _4 b7 l# L- v
  625. /*                                                                                                                                                */; Y# m) m3 \6 |. K
  626. /* Input:                                                                                                                                */5 E9 S; f3 A  s' V
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */. [. j7 g. }1 o0 r$ @$ Q9 i* n
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    - m' U- Y, n! C9 [% B( j0 d. t! ?
  629. /*                                                                                                                                                */7 w+ K7 ^; d- G$ H1 I( I* O6 \* Q
  630. /* Returns:                                                                                                                                */* {, o3 D  f6 P1 {& }$ K# G! e2 P3 I
  631. /*                Nothing                                                                                                                        */6 j$ q7 ^0 A6 d% _8 |( ]8 z8 r
  632. /*                                                                                                                                                */1 g# E4 p  x+ j
  633. /************************************************************************/0 S' f5 B; r3 g( O1 q" R6 @4 I
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)0 f9 F2 B- v$ v/ L1 Y1 V5 R" w4 }
  635. {4 _0 T6 f" S& O/ Q
  636.         unsigned long i = 0;
    3 y" u; }$ _. h. y, M
  637.         CE_Low();                                        /* enable device */
    1 R# \0 x" y3 s: n6 l
  638.         Send_Byte(0x0B);                         /* read command */
    6 h2 a; [7 ?. \( p! U
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    % I- S+ j( k( e
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));/ o$ k2 o/ r0 c& p& @0 J" G
  641.         Send_Byte(Dst & 0xFF);
    # b) N* R0 f. A$ z+ W
  642.         Send_Byte(0xFF);                        /*dummy byte*/1 R4 a4 @* F4 |/ B5 w, r: A
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
      N7 o  Y% x& d5 E; l
  644.         {3 h8 j0 \6 u" b; T/ _+ U0 |' |* i
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    . z% Q' Q0 o3 Q4 @5 Y1 [5 y
  646.         }
    . E6 n, u) \/ X$ \  b$ R! k  P9 V. o
  647.         CE_High();                                /* disable device */
    7 S# X6 i4 y: X1 C5 O
  648. }! v- y0 i6 l4 c  C7 Z
  649. 7 g/ H% }! d/ `7 F8 @) s4 w
  650. /************************************************************************/
    ; {6 h) A! V, o
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    # }2 @( K. i( y& y% E
  652. /*                                                                                                                                                */9 S( o6 T# s4 A  A  @+ Y
  653. /* This procedure programs one address of the device.                                        */4 g! e, ?3 N. x& ~5 E; I
  654. /* Assumption:  Address being programmed is already erased and is NOT        */0 z( F0 P1 Q, t1 C; V% \1 A
  655. /* block protected.                                                                                                                */4 g* {' o* Q' m8 P& T2 ~
  656. /*                                                                                                                                                */9 i; z/ g( w3 _$ R( D2 F& \. z
  657. /*                                                                                                                                                */0 F' A" y/ i, _: n2 e3 b; G/ r
  658. /*                                                                                                                                                */* o0 d$ s5 d; k* U) x: r1 y" _
  659. /* Input:                                                                                                                                */
      G) |/ @/ Q+ [0 g4 j2 J
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    9 C; W, }& c5 V  q6 J1 R
  661. /*                byte:                byte to be programmed                                                                */
    - H4 s  a; r/ z3 \
  662. /*                                                                                                                                      */3 t$ U) X4 v& r* c' ~
  663. /*                                                                                                                                                */
    9 v- X8 x' U: r, ^! A# T
  664. /* Returns:                                                                                                                                */
    6 R+ K- X& Z" j0 H: ^
  665. /*                Nothing                                                                                                                        */& `& J7 Y" o. U$ f
  666. /*                                                                                                                                                */9 j7 g( z: z! W
  667. /************************************************************************/! L! w$ q6 L: u# c" n0 {
  668. void Byte_Program(unsigned long Dst, unsigned char byte)* f2 J3 b# L1 k/ h4 f* J
  669. {
    ' p2 a- D/ S0 l% J* q/ p- w
  670.         CE_Low();                                        /* enable device */# R  }+ B: Q' d$ h( i2 C9 g8 |( j. Z
  671.         Send_Byte(0x02);                         /* send Byte Program command */- h9 C0 U* W- o
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes *// q$ h3 o5 J! F4 b1 c' h
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " U$ r: S, x$ M+ e
  674.         Send_Byte(Dst & 0xFF);
    , ^; w  h% I( E9 B
  675.         Send_Byte(byte);                        /* send byte to be programmed */  J& S! Q2 Y; v; O( [
  676.         CE_High();                                        /* disable device */2 U8 C4 w3 g% H' ^2 M
  677. }4 e; l  X- M. x! A: h2 ~7 h+ k
  678. 2 S% _! g, a/ j* F  Q
  679. /************************************************************************/" m. }' [% M# S( O3 O
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    , ?4 @% }3 z' P& }0 k: p
  681. /*                                                                                                                                                */0 t) H5 i9 H0 v3 ?
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*// p/ z) g: ?. H* J- G  \7 e8 ^( P
  683. /* the device:  1st data byte will be programmed into the initial                 */  x" O- V; @7 Z2 P
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */* ~6 f& v" D( \
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
      Z. o8 J9 \6 i6 n
  686. /* is used to to start the AAI process.  It should be followed by                 */: U  K% \6 B, h. J# @1 t& z
  687. /* Auto_Add_IncB.                                                                                                                */. a8 q* g0 }. J4 H, k; G1 U
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    1 e$ u% E0 C) R, q  Q1 B
  689. /*                                block protected.                                                                                */0 O: l& k; |$ Y) s) N+ c  b9 N% b# d
  690. /*                                                                                                                                                */- T% |& t, o7 ]% x% Y' ?, S
  691. /*                                                                                                                                                */- f: p( m: {! a" w
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */2 E) {7 q  I1 w) L4 l
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */; u3 Z% ?4 G, e4 j+ s) m% O( b
  694. /*         unless AAI is programming the last address or last address of                */! f4 v* ^- Y- r; z* n
  695. /*          unprotected block, which automatically exits AAI mode.                                */3 j+ U+ o+ o* R6 @2 R( F- p
  696. /*                                                                                                                                                */
    & @+ X( _$ i! A
  697. /* Input:                                                                                                                                */
    % k$ U+ `% E! H6 ?
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
      V- }. B6 t4 E# ?8 w
  699. /*                byte1:                1st byte to be programmed                                                        */, \& k! f" R! |
  700. /*      byte1:                2nd byte to be programmed                                                        */
    2 X3 T- T8 L$ W0 |% ?' j& ^/ l7 s
  701. /*                                                                                                                                                */
    0 A2 J) b- t. e# ~+ G
  702. /* Returns:                                                                                                                                */3 Q+ t: g, r' g1 v3 u) R7 \6 [
  703. /*                Nothing                                                                                                                        */$ T! @. T0 L4 i- Q9 [1 k' }5 g+ v0 g& K
  704. /*                                                                                                                                                */
    ; B9 L- a/ |3 V2 `) G
  705. /************************************************************************/
    , ^; a# j: m0 L4 D2 w4 r7 n
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)# e+ @& K! D* k9 l
  707. {
    2 _2 m! S3 e* S; H* T; d  j+ Y
  708.         CE_Low();                                        /* enable device */
    , `$ n2 L- F, x
  709.         Send_Byte(0xAD);                        /* send AAI command */7 w( r# }# P) X4 p6 Q* _/ t6 G6 m, ?
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */# c* d4 b% y9 m7 d3 f, U
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
      \/ ^4 |2 D' t0 q
  712.         Send_Byte(Dst & 0xFF);
    - M9 e) W* Q1 O% z& G/ v1 Y2 Q/ r! I. V
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    ) g9 E( |5 a) R% V4 E+ i
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    9 h, ]: \$ }' V1 P, {7 G
  715.         CE_High();                                        /* disable device */
    * T. `" K- t$ d
  716. }
    4 l1 X# U. Q# D7 A8 U: ^* Z# M0 ?3 b
  717. : b3 j+ p4 a8 u* |* w8 K% V& u
  718. /************************************************************************/
    3 }/ L& `0 t+ m: h" ]6 L0 y! I+ ~
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */, g! V) |* s3 R' n
  720. /*                                                                                                                                                */
    * Y4 I8 H! }4 ~3 J
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/2 m5 ~+ G* n* z; w3 w* d
  722. /* the device:  1st data byte will be programmed into the initial                 */
    8 G3 y9 O7 |; D; R+ L
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */, G, E. o7 x' s# c! r: r
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    9 m! t  K+ Q+ D" y; X& ]- H! r
  725. /* is used after Auto_Address_IncA.                                                                                */
    9 h$ H* B0 ]5 v$ P
  726. /* Assumption:  Address being programmed is already erased and is NOT        */- z6 _2 R8 E3 i2 d8 n
  727. /*                                block protected.                                                                                */
    * \+ q' \4 {$ n& D% i3 W  g
  728. /*                                                                                                                                                */4 X1 ^7 e# l3 r3 O; C! o
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    / S: E4 V0 _! t3 V) j# O4 s! l
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    # _0 Q1 O' k4 `. U4 R
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    $ T* h* i! S' k, p) I
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    5 ]/ ]4 O9 }2 i8 C& i
  733. /*         last address of unprotected block, which automatically exits                 */
    ! {  ^. r- G' o
  734. /*         AAI mode.                                                                                                                        */# n/ w1 X' ^, l) }
  735. /*                                                                                                                                                */" y5 g( p! r5 y0 @/ ~
  736. /* Input:                                                                                                                                */3 |5 A, P; i0 [5 N% q7 B
  737. /*                                                                                                                                                */. z/ E5 Y+ E( o. k" L+ Q3 d
  738. /*                byte1:                1st byte to be programmed                                                        */: Q% a! a' S+ U! t1 U
  739. /*                byte2:                2nd byte to be programmed                                                        */1 d* g# F7 u3 v7 u( E1 }
  740. /*                                                                                                                                      */0 B: k) k! i) d1 U# q4 V3 |
  741. /*                                                                                                                                                */
    7 e. w: R( |0 K- U
  742. /* Returns:                                                                                                                                */! m3 s" u+ h4 U9 N& L' r
  743. /*                Nothing                                                                                                                        */
    ) n* \2 `9 `5 T5 r
  744. /*                                                                                                                                                */0 _( v1 I1 c+ `3 L9 R; |
  745. /************************************************************************/
    % R, z) w- f- w& g( ~" M; [, Q( M
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)( s/ Y+ i2 }6 }2 Z" n7 E# G' ?
  747. {
    1 `4 m; i1 o+ M/ B: l/ Y; C1 t1 B; j5 V
  748.         CE_Low();                                        /* enable device */; Y: G0 M2 v  J* B( O- h4 b1 R! I- f
  749.         Send_Byte(0xAD);                        /* send AAI command */
    8 d6 L/ S5 ?4 b! K
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */% D6 C- I7 C# P% k( h; o( {2 a
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */5 H9 N/ D: A! u) T' i
  752.         CE_High();                                        /* disable device */
    4 Q8 H. t) P5 s2 ~7 r! w
  753. }& M# g3 ]- m4 g. R

  754.   Y, l( ?* D7 l# h: h
  755. /************************************************************************/
    % n6 M0 C; l8 p" I
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */) v3 a6 V4 f# r6 H( f3 @, Q
  757. /*                                                                                                                                                */
    3 a  E( s# g  l" G
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    0 Q8 c: F4 g% i; W; ]
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */) E# q" d$ A6 D7 N, n) o
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    * N4 ?0 |0 |8 C1 Y, J+ {  v
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    " F, U" g& ?* U: R0 P1 B
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */5 g  G4 V' p9 `
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    6 N: n- m1 s* n+ [
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    3 `3 I$ v5 S/ T  f" u% S
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    5 h0 k9 x6 L" o: a
  766. /*                                block protected.                                                                                */
    7 G( a" }0 k, u/ G
  767. /*                                                                                                                                                */# B9 M% N# ?% z- B5 i! M
  768. /*                                                                                                                                                */: p; K- z  @) c
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */8 a4 o4 f* b; N0 F8 M3 \; B
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    " h% ?" ?' ^' w, W
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    & K3 a7 Q! W! B+ b' |
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    0 L8 `9 G- U+ p9 H5 e. N7 r% O; r
  773. /*         last address of unprotected block, which automatically exits                 */$ m* R, m# u$ ~: _6 {4 d
  774. /*         AAI mode.                                                                                                                        */8 Q% k+ P# B. N  X0 y- I$ M  B3 F
  775. /*                                                                                                                                                */. x2 f- ~6 E* B6 B
  776. /* Input:                                                                                                                                */
    5 e! ]  A1 K8 @! ~, v; b5 p
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * ?& J8 V1 a9 |3 e" ]; B. h# Z; ]- L- w+ i
  778. /*                byte1:                1st byte to be programmed                                                        */: G* j& A/ z# R
  779. /*      byte1:                2nd byte to be programmed                                                        */
    1 _( A7 X; J+ w2 ^/ _! C; ~$ ]
  780. /*                                                                                                                                                */
    . D. o# Y. g6 V2 O' Q2 B# P
  781. /* Returns:                                                                                                                                */
    : G% B6 n4 y7 y
  782. /*                Nothing                                                                                                                        */5 R, b1 u1 G) q  l- z
  783. /*                                                                                                                                                */
    8 r7 A& R* n! O3 f
  784. /************************************************************************/
    , \1 o  t$ [) a6 i4 c% d: X
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    + Q* a$ i& F% C$ P6 @' V
  786. {3 K8 X2 E( j( ?- Q/ E/ J# k9 [
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    ; J: B( L, n8 d) t

  788. % Q- `9 ^4 u' o9 i" `
  789.         CE_Low();                                        /* enable device */% L& }0 U4 o! |3 P: G6 {# c
  790.         Send_Byte(0xAD);                        /* send AAI command */  z6 f! F1 k+ a; R
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */  ?% x0 m" u, m/ h
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));7 w% i  j/ Z  S, x0 z' y2 w
  793.         Send_Byte(Dst & 0xFF);5 W9 v3 T5 E8 T8 g
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    ; _7 K$ ~% ~, g! B! A' T+ J/ D
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ( P, ~' D$ E2 p" |9 ^. Z
  796.         CE_High();                                        /* disable device */: ~* R$ n1 R0 U
  797.        
    1 [# d: I8 S: a9 }; P' ?; U
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */: K+ c  {, A7 p5 ]9 e- k

  799. 7 c1 w: ?- N% l9 R" D
  800. }
    4 v3 D5 r3 [8 n7 F* }
  801. - F! d# ^/ q5 Q
  802. /************************************************************************/
    , H% _! V  H' e7 K
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */! H% o! M3 F7 r: U4 W) @/ l
  804. /*                                                                                                                                                */- v2 Y& {9 v$ T
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    ( ]: h7 O$ U) D
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */% l; k0 D) z: ^4 \( V4 A
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    7 v# r$ N0 j0 P( p9 F
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    / w0 O) M) l! K" P3 n6 @3 }
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    * L! j$ T7 {, {& c0 J9 I
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    4 E% d1 u1 R, X% a
  811. /* used after Auto_Address_IncA.                                                                                */3 W* p0 L) y- w3 X
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    & L6 R' V& @* l, j2 o/ a4 q
  813. /*                                block protected.                                                                                */- d, q* K. r3 O: s/ m/ I, a5 u
  814. /*                                                                                                                                                */
    . ^! z4 M8 u: A6 @
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    + a' [0 `7 Y- @$ S% N% x
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */) a$ K/ ~6 d/ I) y
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ' a; H5 F' y1 f% l5 P# S. z9 t
  818. /*          to exit AAI mode unless AAI is programming the last address or                */) J$ J( d: Z: c
  819. /*         last address of unprotected block, which automatically exits                 */
    % I! C; K! ?4 `5 \) o2 g) U
  820. /*         AAI mode.                                                                                                                        */' O7 X9 A. n' j( J" e- @9 V5 ?
  821. /*                                                                                                                                                */! y) m9 `1 F9 i; ~
  822. /* Input:                                                                                                                                */
    ' ]. |5 H! a  \1 m5 `2 A
  823. /*                                                                                                                                                */
    + G* Q& v5 \! q7 v) _+ L
  824. /*                byte1:                1st byte to be programmed                                                        */! A# D8 b2 T& K9 W4 }+ }+ [8 L$ U
  825. /*                byte2:                2nd byte to be programmed                                                        */) q6 ^# s/ [; o- L9 I( ~
  826. /*                                                                                                                                      */  f3 A4 _+ z; L% E$ J% J) N1 [
  827. /*                                                                                                                                                */$ }) }8 A6 _. l% |! i4 |, S% E
  828. /* Returns:                                                                                                                                */
    * w. t( r5 `/ t2 O& k
  829. /*                Nothing                                                                                                                        */) L) u% r/ I& n, Y
  830. /*                                                                                                                                                */" T* c! @$ J+ Y; W5 }& p
  831. /************************************************************************/, h7 p; f8 _2 ^" e
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)2 T" d2 q. q- c( s# v+ d  `
  833. {$ D  l; t7 Z+ p8 B) _
  834.         CE_Low();                                /* enable device */% e; U! }0 v$ `6 q- c0 s% L1 [
  835.         Send_Byte(0xAD);                /* send AAI command *// I* L3 q6 z8 T
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */0 W. a( d/ _6 }8 P9 q
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    " o& e$ A; x8 u: c5 j6 P9 p. a: k( y+ M
  838.         CE_High();                                /* disable device */- i0 p/ Y% {2 j& L/ H
  839. + k( i6 O: K! I8 Y+ R' ]
  840.         Poll_SO();                                /* polls RY/BY# using SO line */. s  c4 h7 h8 t
  841. * C! c/ G# ~+ i
  842.         WRDI();                                 /* Exit AAI before executing DBSY */! k# z( o8 o& G
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    5 H6 t8 r" H. N/ O7 X. v( G
  844. }
    4 I, {: Z4 U+ Y6 \3 X. y1 j

  845.   V/ H# b! f" T% o# {
  846. /************************************************************************/5 ]* [. r- i2 _8 M0 h
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    3 L3 O& o9 b$ @$ H' Z
  848. /*                                                                                                                                                */
    3 ~- x& j" |/ {' N3 L7 {' I
  849. /* This procedure erases the entire Chip.                                                                */2 @/ k6 U- N# d
  850. /*                                                                                                                                                */7 k; E% L6 T/ K6 m
  851. /* Input:                                                                                                                                */
    6 V5 B: p( E+ ~! K6 [
  852. /*                None                                                                                                                        */
    " T# a4 e; c0 @) G1 {
  853. /*                                                                                                                                                */4 `$ O4 h4 z2 y- J7 n( f) `" _
  854. /* Returns:                                                                                                                                */) P* ~/ {: d3 o4 U; \" O0 ]
  855. /*                Nothing                                                                                                                        */$ L- D( u$ n/ G& i% i
  856. /************************************************************************/; Q) }! D; x* l
  857. void Chip_Erase()2 O1 J% b2 z. V0 u$ R# D2 R
  858. {                                               
    # `* V+ d, e2 u- n6 N7 x
  859.         CE_Low();                                /* enable device */
    6 E) A; j3 J0 X  u
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */5 o0 T$ s! A/ h* H, V
  861.         CE_High();                                /* disable device */1 e8 p3 F( S4 ?8 p) f
  862. }
    ! M& ^* I7 c* L: P+ q8 m8 X

  863. , H- B' z. X, l
  864. /************************************************************************/' V/ N: A8 `2 s2 o
  865. /* PROCEDURE: Sector_Erase                                                                                                */8 g# H+ s: ~: z& O% `
  866. /*                                                                                                                                                */" [, z3 Y5 J; b! f
  867. /* This procedure Sector Erases the Chip.                                                                */
    9 b; L) g9 \8 Z! q5 ~: P1 X" Z
  868. /*                                                                                                                                                */
    . g! f# ?* Q" W' b5 v2 @
  869. /* Input:                                                                                                                                */4 y1 z0 N& r: {/ Z. _
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    " {$ _; k3 C! I; M
  871. /*                                                                                                                                                */$ ]/ Y6 \' Q+ [8 b- F- g
  872. /* Returns:                                                                                                                                */7 ^/ Q  \, G- n7 @. \7 P0 G0 x
  873. /*                Nothing                                                                                                                        */' D: g% J  e" u) |3 {$ \! b
  874. /************************************************************************/
    ! h& r/ a) b7 m" X4 Q" U$ q
  875. void Sector_Erase(unsigned long Dst)' n/ s! u" s' g/ G1 T6 n
  876. {
    & a; _7 k  X$ n. N
  877. # e# d) J1 n$ l- {9 q6 m* j* B# Y
  878. ( z7 x3 U0 {$ u0 L* f( O8 Q
  879.         CE_Low();                                        /* enable device */* s/ B" r  h0 ^  F' K9 `$ B; E: q- T
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    7 ~4 y% G2 W! v
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    # v1 A# \' e6 @2 l
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));! y7 U3 U9 h. B; U( N
  883.         Send_Byte(Dst & 0xFF);
    0 s% ^% P# K+ N  c0 g
  884.         CE_High();                                        /* disable device */
    0 V7 r; d$ C! K
  885. }        6 P: v5 }8 a, [0 I
  886. $ s1 O) ^! J, u3 y" a  f
  887. /************************************************************************/
    * {, g" h% u4 q) e
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */* g; x+ R. i4 S7 `) ^
  889. /*                                                                                                                                                */2 D/ t0 h, [4 i+ |! `
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    6 E) t3 {. x/ V0 B6 e
  891. /*                                                                                                                                                */
    0 A$ u3 @# C: t5 _! D
  892. /* Input:                                                                                                                                */
    " y5 K- x8 X% x
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */* K! h3 R2 s$ |  h7 S
  894. /*                                                                                                                                                */$ }( \. w1 s  P; D" w
  895. /* Returns:                                                                                                                                */+ N% I6 e( k/ g+ d% I3 [
  896. /*                Nothing                                                                                                                        */9 j7 c: `/ ?$ F( j; O% s
  897. /************************************************************************/: t4 P+ _- Z  V0 J1 j5 a$ `
  898. void Block_Erase_32K(unsigned long Dst)
    # O, P. e2 {3 y6 R% n6 Q$ n! n
  899. {
    * |) b4 ]3 {0 t4 s
  900.         CE_Low();                                        /* enable device */( p2 T! q$ y4 N  U/ i. `
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */5 e& o, [  c- u' a1 p; j4 t
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */' U* l' I! }! S. p5 V- m& o
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    & d& G; ^8 f' f6 g& L) m. M
  904.         Send_Byte(Dst & 0xFF);
    ) S! i: \+ H# c3 e
  905.         CE_High();                                        /* disable device */! z# \  J7 O5 _" z+ b* x
  906. }
    1 Y3 J2 H' w% `) q* _4 D1 k1 m
  907. $ s4 Z# K% Y; B
  908. /************************************************************************/# Q4 f& a. x$ O9 D' K' s
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    1 M, n6 X, D% A7 P' e
  910. /*                                                                                                                                                */  g+ B; p) l# R3 x, {
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    : s4 O) s( V4 t; |4 F
  912. /*                                                                                                                                                */
    $ ^) ~: t$ D' Z
  913. /* Input:                                                                                                                                */
    9 O/ V( \- p8 `0 }
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : r1 s8 ~4 d0 N$ @3 i
  915. /*                                                                                                                                                */
      P% M5 D$ b6 s5 E& ]3 I$ |& V* Q
  916. /* Returns:                                                                                                                                */
    8 p  b6 ?% d# g0 }, Y. f
  917. /*                Nothing                                                                                                                        */
    0 c  U5 C1 o! T! |: i4 j$ ?
  918. /************************************************************************/
    2 ~3 A4 m( @8 J  Y" ^! N1 P/ t
  919. void Block_Erase_64K(unsigned long Dst), h4 l' x# E' b4 z" x; {+ ]4 [
  920. {
    * Y1 ^& s# p! g$ L
  921.         CE_Low();                                        /* enable device */9 b: Y3 q/ H5 J: Y& X& s
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */3 u" k) P; }+ c* B
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    6 s/ j1 u9 _7 d6 N
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ) _! x' a% x( ~. Y$ Z
  925.         Send_Byte(Dst & 0xFF);$ K2 u+ x$ X) O/ Z
  926.         CE_High();                                        /* disable device */
    2 X" k9 B  Y' U  U/ [2 N: Q
  927. }
      ^3 x: X! X  _8 o, S! U! f# V. i
  928. 0 p( X! H, I6 r8 a
  929. /************************************************************************/
    + W# W! j5 ^: j$ u9 {' N
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    8 n1 p1 U( P$ m3 G( Y% q
  931. /*                                                                                                                                                */8 J5 E! o) y  |% [
  932. /* This procedure waits until device is no longer busy (can be used by        */2 P+ i  m  Q2 H/ O; B" X0 ~2 Y) `4 D
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */# {2 `) r1 ^& o3 I" s
  934. /*                                                                                                                                                */
    ) n$ n4 i1 u9 `& z/ I! \
  935. /* Input:                                                                                                                                */' g7 h3 D+ Q# j9 i% G/ J
  936. /*                None                                                                                                                        */0 h" r- D8 Q! z+ Y
  937. /*                                                                                                                                                */; @$ K: j: O3 p$ O
  938. /* Returns:                                                                                                                                */
    / P6 k! T- _* Z2 s% k) Q
  939. /*                Nothing                                                                                                                        */
    6 F% w# R! F& Q: v) @! ]
  940. /************************************************************************/7 H: X3 T: v: \6 l5 o1 X
  941. void Wait_Busy(): s! s# V3 a  E  l
  942. {
    % P. Y6 i! V  I* j
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */2 ?6 B9 W: w# ^3 C. T& Z
  944.                 Read_Status_Register();: \% `, I- }5 `& `( [
  945. }- {# c( l: J9 h& N) ~7 i% S8 ~
  946. 1 _# r' {9 y! }+ g4 h5 H0 a
  947. /************************************************************************/
    4 y0 n; H. o0 k% D& @
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */2 g& c/ g! Y: U' U' [% \" p' H
  949. /*                                                                                                                                                */( b6 ]% [/ K+ W$ _; _0 y
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    : ^) K8 r! u  K: V" r
  951. /*                                                                                                                                                */
      n+ M9 \4 R' R/ ], {
  952. /* Input:                                                                                                                                */
    + G) ?2 C5 Z8 ~- H% O0 S1 \! {
  953. /*                None                                                                                                                        */
    5 I4 b7 l2 H* n7 U
  954. /*                                                                                                                                                */+ y, I6 v9 {: [9 y( m% p0 w1 F3 K
  955. /* Returns:                                                                                                                                */
    ) ?0 ]& I0 h3 ?, Z
  956. /*                Nothing                                                                                                                        */' F! i! ^6 ]6 k- V& |
  957. /************************************************************************/
    0 x# s& T! a5 }0 n, j4 K
  958. void Wait_Busy_AAI()0 J3 C3 c0 Z1 j- z
  959. {  k: K" T' {4 L7 e  D+ b! E* U4 `
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    / L$ N3 E- ]! v* Q; c  S
  961.                 Read_Status_Register();
    + \. V: J3 B! j. d
  962. }
    7 L  h3 C- S: ~+ N4 S6 E

  963. ! O5 k$ q) ~9 O
  964. /************************************************************************/; v/ a( Y5 X7 a: p, o
  965. /* PROCEDURE: WREN_Check                                                                                                */
    3 h  {7 N% @# [$ u2 _
  966. /*                                                                                                                                                */
    : @) l8 ~7 G$ u- w2 }$ g7 t) L
  967. /* This procedure checks to see if WEL bit set before program/erase.        */& J2 @+ X1 J" W( r5 S4 O# b' e
  968. /*                                                                                                                                                */% S$ w" |, x! C" P  \5 V4 I7 Z4 x
  969. /* Input:                                                                                                                                */7 `+ K& H/ ?" c: M# [( S
  970. /*                None                                                                                                                        */
    ' F- c: @) F8 r: G. k$ C
  971. /*                                                                                                                                                */" e" @# u: A7 p, ?/ c, E9 d$ l
  972. /* Returns:                                                                                                                                */
    . j$ D. A! x" r6 s& t! X
  973. /*                Nothing                                                                                                                        */5 u* [  X0 a4 A! r
  974. /************************************************************************/
    - c# `8 p: R+ Y: y
  975. void WREN_Check()
    5 j* v- U+ D( h1 O1 O
  976. {, k# ^, s/ K* }; v% N
  977.         unsigned char byte;0 O9 {  M( E4 s/ o* F* g! h
  978.         byte = Read_Status_Register();        /* read the status register */
    , k4 ]9 Q0 x( L3 h6 U: m' B; ~
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
      G( q  F1 g+ e( j& V' d; W$ y
  980.         {
    8 f  P7 ^% t" ?) {5 ^3 ?
  981.                 while(1)4 p+ P4 T4 F8 }) u
  982.                         /* add source code or statements for this file */2 C" p+ R' L( [
  983.                         /* to compile                                  */$ K) e; g" B8 Z
  984.                         /* i.e. option: insert a display to view error on LED? */
    , @- I; I. E. s2 N' m' D
  985.                  9 S3 k2 d; w- \8 H+ O  @! ~; T
  986.         }: `8 ~) Y' j8 x) k2 f/ Y; _
  987. }) P$ A9 F/ W/ l" j7 T( G& v
  988. 1 S( @* ?, c$ t( U7 D
  989. /************************************************************************/2 B9 A* |+ g" T4 L& _
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */& c: Y. g6 V4 C9 V
  991. /*                                                                                                                                                */
    6 _( e& N1 G$ z0 w
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */8 ]  [  s7 H5 b3 L
  993. /*                                                                                                                                                */" Y6 z  e/ v/ o# g9 B" f
  994. /* Input:                                                                                                                                */7 H2 l+ k5 m7 k0 u& \3 t6 }
  995. /*                None                                                                                                                        */
    5 }2 r/ S2 M! _, K
  996. /*                                                                                                                                                */
    1 n4 x. C  B; U1 l
  997. /* Returns:                                                                                                                                */
    6 W( o. o2 c% n  S
  998. /*                Nothing                                                                                                                        */7 N( @1 J: ~9 o% L  [1 i
  999. /************************************************************************/
    2 i/ H$ h+ l( ]9 u4 {: f
  1000. void WREN_AAI_Check()
      l- N' j# T" \0 ]! W& ]
  1001. {5 E& h. |% Q. v' Q" n: ]5 C6 A+ Z5 _
  1002.         unsigned char byte;
    ! d1 Q* i) P. D. H0 B0 @/ ~
  1003.         byte = Read_Status_Register();        /* read the status register */9 X2 Q# x3 \& Q! C! s
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */- o( g' V3 ^: d! d* P7 B3 g1 c
  1005.         {
    3 \  e- C8 k3 v; G# o
  1006.                 while(1)               
    % t8 x6 f- `$ N# F
  1007.                         /* add source code or statements for this file */
    # p! P8 d+ S5 Q8 k2 g/ v: o
  1008.                         /* to compile                                  */
    4 N' D# s/ ?0 @! I- P: ~
  1009.                         /* i.e. option: insert a display to view error on LED? */4 u1 O9 a* W+ M, x$ d% M1 l

  1010. 7 I! H4 B1 H1 i3 ?4 f0 b! n; p. h+ X
  1011.         }
    $ Z* e$ a- o* F
  1012. }
    , x+ \5 j* D  B0 l
  1013. # M5 _3 i  x3 S" A* E
  1014. /************************************************************************/
    0 N4 P& B5 P4 z& G5 u) j& l
  1015. /* PROCEDURE: Verify                                                                                                        */
    ' D1 X( g' j: ]9 `# E# W
  1016. /*                                                                                                                                                */5 S+ s9 b8 p8 S. Q- K
  1017. /* This procedure checks to see if the correct byte has be read.                */4 p2 _& t6 z  D$ P" Y, M
  1018. /*                                                                                                                                                */
    ! }3 O$ V9 \+ L* s  y' ~
  1019. /* Input:                                                                                                                                */' }  i) X: }# u5 G3 k/ G
  1020. /*                byte:                byte read                                                                                        */6 O7 c8 H4 F6 K- \
  1021. /*                cor_byte:        correct_byte that should be read                                        */) z: \: u) Y- e% }2 u+ ?
  1022. /*                                                                                                                                                */  M# V4 |! d4 }0 ^* _9 a
  1023. /* Returns:                                                                                                                                */* w( T1 N; Y6 ^5 }- B% x5 M5 Q
  1024. /*                Nothing                                                                                                                        */
    + |4 I5 l. k# I
  1025. /************************************************************************/
    4 [; U6 [9 j# g
  1026. void Verify(unsigned char byte, unsigned char cor_byte)  d  B% N+ o) q) J9 x4 s
  1027. {& N/ z- L. |/ w+ f2 A
  1028.         if (byte != cor_byte): i4 u" V  y3 X$ ?! x) ?
  1029.         {  u8 W- |# X0 p" ]1 Q, E0 E
  1030.                 while(1)7 a3 X9 f# H2 g: q3 C9 j/ ~
  1031.                         /* add source code or statement for this file */
    * w, Y7 D" I- [0 t% ]$ s
  1032.                         /* to compile                                  */
    ' H+ p3 Z- @  P, n  U' S
  1033.                         /* i.e. option: insert a display to view error on LED? */! S$ X, o* i0 S' Q
  1034.                
    3 _' D6 B+ Y- c( j. o
  1035.         }7 {  R- z3 |3 v2 C. v3 z
  1036. }$ R& y+ `: ^: u" W; u

  1037. ( g3 }2 C# g( V1 _  w: E
  1038. 8 |( q* o. l6 E1 W# `( P* V+ U3 Y
  1039. int main()
    4 R: k/ j* n* z. {' u. ?
  1040. {
    ' W- T# w' e* J8 Y. v- t
  1041. & ]4 m; s2 H! g8 Z7 r0 R4 B
  1042. return 0;; B) |% d( O4 D; T5 C, r% a
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:5 K1 O/ N& D5 p+ C6 O
   main()) u% }7 q4 J( C  _5 R
   里面怎么是空的呢?
! y! r" D# q2 L  g9 t& a   发一份给我吧
  L$ x( k4 N9 L9 X( Rmail:luyijun2005@hotmail.com
0 r( x* e% K' s咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
8 {# Z+ h6 D$ L3 o$ J+ e! [1 E+ D8 _5 ~- V) _& ~* I5 P5 n
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
- M0 L3 o, R- s3 ?EC的代码在哪跑,你看DS的说明,每个EC都不同的。
7 J% I  W! a! U5 o7 aOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?5 i! w* v! A$ {5 a1 Z! F8 X
上面几个问题是你没看任何东西而白问。
) \( W, d; N' k: A" h$ j2 }
2 i( J, T5 \+ J& A# v, s至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。0 L: s9 d0 S: s1 O

! J& p+ f% [3 o7 n  \4 T0 |关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!- H' v$ G; A0 [
% n2 e% u6 D# O2 e/ A& f
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
' L+ E( V2 Z& A+ W, Z! W9 d% A5 C" B% V/ ]
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...8 E2 R/ A6 F& h: [$ V
( }4 p3 e7 c$ E" }6 T+ U
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
9 y% s' W, J3 K9 t" o似乎要把SPI能support 到最大,这EC chip应该有好卖点7 @( r: @. ^0 t3 x5 t, J
BIOS功能要不要强大,也就决定了SPI Flach的大小
- u9 S" {: f1 K$ o2 I我是这么想的~让OEM去决定要挂多大!- `  p( j  g2 b, T4 }/ s: o
如果我司有BIOS工程师就好了~哈
* r) A, N9 f! gWPCE775应该算很新的东西,来看它支持到多大?
5 h$ N/ ^% L% v4 B/ _) v  f/ L1 @$ Z5 N& Q  @0 S* D
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
' r( V3 R: n) S. F其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码." \9 i: g* f& p* F/ B
& ]3 S0 E1 T; z, }, U4 j
这份driver收下~希望以后有用到5 L5 O& l" t; D* a+ W. w( z
谢谢bini大大- B( `9 D- R" \/ A" |( F7 V

, P9 ^! d2 d0 v很新很新的新手,如有错误请指正 (准备看第二家的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()5 P( h* z; m& [
{
) ]+ s/ H1 W7 R9 w4 g        unsigned char temp = 0;
* I/ [9 |2 X8 t( E$ P        CE_Low();" Z6 G) b* K# O
    while (temp == 0x00)        /* waste time until not busy */
3 N( [$ q% e7 R3 H                temp = SO;
+ `/ ~$ ~! J# q" ~        CE_High();
2 p9 h, ]% b! a/ n: r}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)$ g# d  K" R$ e9 A# i1 m
{
3 M; N/ V" E, B( }        ) Y: y1 v8 s; v) d4 M# j
        unsigned char i = 0;
8 z1 ?' c- d! C! u        for (i = 0; i < 8; i++)- P) g0 A: l# M2 u0 r' K) V
        {( N/ P' `  v0 K! ~+ t# K
                , r1 `4 r* H6 Y7 W+ Q. i+ I1 r
                if ((out & 0x80) == 0x80)        /* check if MSB is high */, g$ F0 H- E3 W3 B
                        SI = 1;* Z1 f! D, U1 E" ~4 e+ ?* S
                else
% v: v% E# R) W6 I+ Z                        SI = 0;                                /* if not, set to low */
& I: Z1 L1 C: d" l9 S 问              SCK = 1;                                /* toggle clock high */( K: }0 M7 d; B# m% K6 Q# D
   题            out = (out << 1);                /* shift 1 place for next bit */- l+ M3 L  ?" B1 U& r* _
                SCK = 0;                                /* toggle clock low */
# @" {* X  q5 h) J8 r& }0 S3 T        }
4 G& O6 p3 j: b. Y' v}7 N3 {) \0 W- Y$ {' W& y0 D
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-2 11:02 , Processed in 0.061686 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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