找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54826|回复: 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
    . k0 }1 |' u+ F  \9 k2 t; d$ M
  2. % c) \1 M" h0 A% }- y! l
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    0 f9 M+ s8 D% y
  4. 2 |+ U  U4 Y" x
  5. November 4th, 2005, Rev. 1.0
      Q  L- ?/ O! ?8 L9 |
  6.   m  v: w) P$ H* U/ E0 q
  7. ABOUT THE SOFTWARE0 G: b, a, Y: t4 T$ Z/ O: A* }2 u+ H
  8. This application note provides software driver examples for SST25VF080B,# a  E; Q$ q- H$ W: R, c
  9. Serial Flash. Extensive comments are included in each routine to describe
    3 ]3 r! H4 e. `( u% [' r
  10. the function of each routine.  The interface coding uses polling method
    ' ~* u6 x/ r& W1 h
  11. rather than the SPI protocol to interface with these serial devices.  The
    9 B8 O+ ]3 T  C
  12. functions are differentiated below in terms of the communication protocols4 U( J* q" n3 T! t* s
  13. (uses Mode 0) and specific device operation instructions. This code has been 2 s7 E! r; T$ W, a: ]" E
  14. designed to compile using the Keil compiler.
    5 r4 d- g- {" m: Z) |8 {
  15. ; h6 ]+ \2 ?. b% a/ @
  16. ; s* |9 j$ P& {7 R! C
  17. ABOUT THE SST25VF080B$ p. B& j# G$ c! N) z( q
  18. 1 `; S" g% p5 Q6 x& P" x& n
  19. Companion product datasheets for the SST25VF080B should be reviewed in / {( ~# v; e% O
  20. conjunction with this application note for a complete understanding / e# l& E; J$ m7 K1 F
  21. of the device.
    9 s" K3 E8 C" j+ X
  22. $ @& m& j/ U( t9 t! i9 Q, C
  23. , Z$ @2 B' G; ]- s9 `3 g7 ~7 z$ p
  24. Device Communication Protocol(pinout related) functions:
    ! Q0 ~0 S6 E, ]: D7 `
  25. 8 w/ E- b* [2 D5 w- h
  26. Functions                                    Function
    1 R6 D% G, t! l
  27. ------------------------------------------------------------------
    8 d, u7 ~/ T' ]0 t, [
  28. init                                        Initializes clock to set up mode 0.! n0 H$ Y3 d$ A9 i8 _
  29. Send_Byte                                Sends one byte using SI pin to send and - A; Z' ~$ N8 J$ z& D& z& _9 g; d
  30.                                                 shift out 1-bit per clock rising edge2 U3 j( @- K/ J+ |& x+ `6 {2 V
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    0 j8 d2 b0 f8 E" P, O
  32.                                                 in 1-bit per clock falling edge
    + G2 \. E, C5 K- u$ D* `
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    # c: _  C( ~7 \& _% E$ t
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    - ?$ p. a2 Z( F5 G& Z% w
  35. CE_Low                                        Clears Chip Enable of the serial flash to low- m% b6 ?: E1 M8 D6 ^* z, F
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    . M. P3 v; T. `3 m7 n
  37. Unhold                                        Unholds the serial flash
    : @- C+ ~$ E$ d# w, t' {* p0 C9 e. r+ _
  38. WP_Low                                        Clears WP pin to make serial flash write protected$ V: g/ W; g3 ^9 l4 z' ?
  39. UnWP                                        Disables write protection pin9 l1 L3 V& d' {& Y; m' l/ ~

  40. 0 w& ^' O) B6 p3 R, p
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code6 F+ D4 @* Q$ D% S
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your/ s/ R( `7 R4 X' ?6 \! q0 R
  43. software which should reflect your hardware interfaced.          
    / r7 I8 H- b8 T9 N# _1 `  Z5 O2 b
  44. 9 X* F- `  ?) `, J; K$ Y
  45. : Z$ n8 N( {9 p4 N
  46. Device Operation Instruction functions:8 k5 J, k3 [* U+ E" R
  47. " C- r* _/ v( A  k6 m. h- q
  48. Functions                                    Function
    5 J! g: N7 X) e( k4 T5 M
  49. ------------------------------------------------------------------
    : U7 ?1 z1 J% c: E
  50. Read_Status_Register        Reads the status register of the serial flash
      i" r0 B% ~0 D8 ?8 a% o% o
  51. EWSR                                        Enables the Write Status Register. C% |8 x! J& P7 l. S& b, ~
  52. WRSR                                        Performs a write to the status register
    + q: a2 f8 [0 W+ x8 b. O+ ?; M
  53. WREN                                        Write enables the serial flash5 m# T# f& u8 J
  54. WRDI                                        Write disables the serial flash
    / i  o: N! o% P
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    1 f% R) p9 L7 U1 }* H1 E
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    6 C3 [5 X( u1 M0 C9 Y
  57. Read_ID                                        Reads the manufacturer ID and device ID7 ~$ ~) T0 {# O- M
  58. Jedec_ID_Read                        Reads the Jedec ID1 u+ U8 V) }* @& e0 c
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)5 P  J8 W1 k: D, |2 C( p/ J0 l0 l$ y3 d
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    ! c# k3 h4 d/ y/ c) c8 Y; H$ Z
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    # H; W) k" S  K9 j5 _  o+ F
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    8 q( @. t+ u. D0 g" H6 \4 @- a
  63. Byte_Program                        Program one byte to the serial flash
    4 n/ D( e6 J* B) D, h
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    3 J' \5 ?9 x- e( D
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    : b5 p8 Y8 ^: h1 X. L
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY1 M; `8 H& r, Y3 M! }0 _
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    6 z, [* H$ r6 b- O. I
  68. Chip_Erase                                Erases entire serial flash/ }  G7 D$ B6 Q  d8 |/ [  o, q
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    ; k( e% s( ~# A7 S* M
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
      K7 G' \* Z/ J* t; l0 c
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    : e! d8 K: _; [5 u& p
  72. Wait_Busy                                Polls status register until busy bit is low0 d* c- {0 b) B8 f3 |
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    , `5 U7 b9 q: _& b! Y
  74. WREN_Check                                Checks to see if WEL is set; I7 k4 |9 x; x: b* K; d; N' G, R
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set/ R" @; E  C! _
  76. 0 `% V( s* x9 q2 f( c2 `7 g2 Q  `

  77. " P2 R4 K5 Q8 V! g/ n0 I/ v
  78. , m5 ]% y6 p; X' f( t6 n
  79.                                                                      
    . ^$ ?9 R5 C5 ~- v/ {. _1 h
  80. "C" LANGUAGE DRIVERS % ]. T4 N! K7 Z' c
  81. % `' Y4 ?5 s0 h1 X
  82. /********************************************************************/
    2 R. f; n+ w9 N# ~# e. c
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */2 O6 b5 a* E# \7 }1 Y
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
      |4 o& @5 c! Z$ e
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    1 R8 Q# h" B( m
  86. /*                                                                  */% n5 {) R; Y1 T# Q/ V0 U5 ^
  87. /* Revision 1.0, November 4th, 2005                                                                          */   5 y" ]+ I7 b3 }7 h! v9 h3 u
  88. /*                                                                  */
    - i& ?: P! y; Y
  89. /*                                                                                                                                        */
    # _* ~9 q- S. ^) J! ~+ a3 G
  90. /********************************************************************/
    " X$ b) m/ Y, K  z

  91. 7 L( J( H9 L& o. [% W# |% |  U( q/ R1 T
  92. #include <stdio.h>" F! e: g4 t! D, x; v5 e  f
  93. #include <stdlib.h>
    ! i& v5 ?# f- |" U
  94. 6 U$ J  e: y+ x2 P
  95. /* Function Prototypes */
    , g  T8 [  m4 v- t

  96. 2 ^9 F$ i: i* ?
  97. void init();# x7 |  Z: J& ?  C
  98. void Send_Byte(unsigned char out);# k* X. B3 K- g! C5 |& b2 ^1 @
  99. unsigned char Get_Byte();
    1 M' `. {( Q; n* [! ~
  100. void Poll_SO();
    ( f9 T# b7 _7 A5 x( Y; P
  101. void CE_High();
    9 ~) M7 O8 ]  I6 X; w
  102. void CE_Low();
    1 w; B5 S0 T# {: P$ B6 n2 B
  103. void Hold_Low();  f0 D7 G, g$ W$ A
  104. void Unhold();. N$ V( Z* L9 s
  105. void WP_Low();
    $ Y7 V/ j- p7 H+ ]. s( z4 P6 C
  106. void UnWP();7 t" H  q8 G5 |+ G
  107. unsigned char Read_Status_Register();6 ]/ X: j. N) [4 I
  108. void EWSR();
    $ s5 L+ n+ R! W  q2 H* ]' R
  109. void WRSR(byte);
    " }/ c, Q: u( x( i5 {6 w5 K! p
  110. void WREN();' v& p! d" g. \8 w! \$ W. }& y! }
  111. void WRDI();
    ' W: j8 i5 e/ r. p5 S# u( Y
  112. void EBSY();3 ~: O) c; S  _2 x
  113. void DBSY();4 Y+ K0 ?. Q' N+ d4 W
  114. unsigned char Read_ID(ID_addr);- K" }% |2 u& d
  115. unsigned long Jedec_ID_Read(); $ G, `1 v5 T7 `+ y
  116. unsigned char Read(unsigned long Dst);* I. n1 M9 M  {6 |" J+ E8 o& {
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    + \0 {8 F$ q0 O0 k" H+ }. Q4 k) v
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    ) @& a8 A: Z; P5 E* [2 g
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);% ^6 E' a1 t; R. E' i7 x
  120. void Byte_Program(unsigned long Dst, unsigned char byte);# Y5 [2 r3 D+ \% m
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);- @* E# V+ \  `9 y$ U) W$ Q
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);  S% b. m( d; z1 K
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);! m( ^3 Z2 N* e, |6 ]+ q/ I
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    * Q8 I9 L. ^6 M& _6 e! d1 D
  125. void Chip_Erase();
    4 H) E2 t3 ]  \4 T" P5 ~
  126. void Sector_Erase(unsigned long Dst);
    ! `) A7 D" S9 \. }! [; r
  127. void Block_Erase_32K(unsigned long Dst);1 L( h9 K. }+ Q+ y: x  _
  128. void Block_Erase_64K(unsigned long Dst);( M6 _1 @4 N9 v& B+ F+ ?& h
  129. void Wait_Busy();/ S5 `: g7 L! @( V# ^
  130. void Wait_Busy_AAI();1 G' C3 c# B' z# ]& m
  131. void WREN_Check();- G) R& Q0 z+ s0 P+ R. K
  132. void WREN_AAI_Check();  l9 D1 I7 c: S, H. o9 C* _

  133. ! ?, g5 s0 K2 e# M  |
  134. void Verify(unsigned char byte, unsigned char cor_byte);: |7 c7 g7 c( S

  135. 5 g: D, ]- p. U$ ~
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    3 k1 C% y* {# P) X+ H
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    7 @* V( ~, \+ Q6 h

  138. , |! z0 `8 Q7 u% H
  139. /************************************************************************/0 f8 n: N  M# T& k. [! o
  140. /* PROCEDURE: init                                                                                                                */$ N5 f$ J9 \" f7 C6 }6 R
  141. /*                                                                                                                                                */' c, r7 d, L. x- h
  142. /* This procedure initializes the SCK to low. Must be called prior to         */3 f: [. F7 }) B, i* ?8 m, v. Y4 O
  143. /* setting up mode 0.                                                                                                        */
    4 F+ C) q' l# I- u& |4 m! v' a$ q
  144. /*                                                                                                                                                */
    " Z7 N2 [, V) I! |
  145. /* Input:                                                                                                                                */
    & f8 E  _* R+ R0 D" `
  146. /*                None                                                                                                                        */- s% l/ _7 O: r% t1 V. W
  147. /*                                                                                                                                                */
    2 I3 J; w# M! j/ E5 ]
  148. /* Output:                                                                                                                                */
    0 u1 q. G# V6 _4 P2 F, M, M
  149. /*                SCK                                                                                                                                */
    2 P) B( a* Y% s" e4 t
  150. /************************************************************************// p1 _6 S8 S+ X, R# E1 l
  151. void init()8 e: a3 p% `" o9 H; G# I0 g8 q
  152. {) G( Z0 V; |* k% v, E% |0 v" K
  153.         SCK = 0;        /* set clock to low initial state */
    $ x1 ?& q  h# @" C1 O) w
  154. }
    2 j: r+ A6 n; N8 f, o
  155.   C. ^0 s: {5 z
  156. /************************************************************************/
    0 g5 x+ v. v5 v3 U
  157. /* PROCEDURE: Send_Byte                                                                                                        */( e' e9 O0 f& ~* s
  158. /*                                                                                                                                                */4 t$ O4 k! D: g$ k# k  v
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    * D2 @5 c/ ^1 w2 M6 r( }& N2 w
  160. /* edge on the the SI pin(LSB 1st).                                                                                */) Y* k3 W, p4 B! H0 N
  161. /*                                                                                                                                                */
    8 P7 g& m5 l' e1 M5 x
  162. /* Input:                                                                                                                                */
    0 J: t& a; _) P$ t. @% A
  163. /*                out                                                                                                                                */  @( w& T9 M/ {  f4 d0 |. g& ]
  164. /*                                                                                                                                                */
    9 |4 P* v7 `8 Z0 ?( }' ^
  165. /* Output:                                                                                                                                */
    * e; a3 [7 R8 @& i7 c/ A1 G. y
  166. /*                SI                                                                                                                                */; g8 a8 y) q+ o) T# |- k$ p( r
  167. /************************************************************************/
    ' R! `" [3 G. h/ R0 ^8 w8 E
  168. void Send_Byte(unsigned char out)0 J' z: y: p( Z* Q' d
  169. {
    , R  E# [3 S5 _* q  W9 |
  170.        
    3 y. s6 ^* i" v0 ?; z2 w
  171.         unsigned char i = 0;  W9 ~8 W: i, @& U9 e/ M, }6 l4 M
  172.         for (i = 0; i < 8; i++)! m0 E# c+ j5 B. V2 p4 x
  173.         {
    6 `  P' q$ y3 ~! |, T
  174.                 4 w! X/ ]& ?1 _
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    , g: h# `2 ], o8 _% f+ d
  176.                         SI = 1;
    # g, z; s7 A0 ^6 m4 F$ ~
  177.                 else. C5 I. T4 B4 F$ }4 Q
  178.                         SI = 0;                                /* if not, set to low */
    8 W0 u! D7 d5 V+ Q6 P& v. W
  179.                 SCK = 1;                                /* toggle clock high */
    1 `- \- I. F  Y6 J; X. H3 Y
  180.                 out = (out << 1);                /* shift 1 place for next bit */) U/ E1 T4 E& `, e' @1 \  N
  181.                 SCK = 0;                                /* toggle clock low */
    4 ^' G3 f0 U1 J; v/ A  s
  182.         }/ u. p) K9 V$ p1 f$ Q
  183. }4 d" F8 C4 F* g7 u

  184. 9 X# J' P5 L, X5 K
  185. /************************************************************************/% M1 @3 s% l" l* B. @0 E1 C* X
  186. /* PROCEDURE: Get_Byte                                                                                                        */2 w6 L3 ]: p1 c9 V2 J' f
  187. /*                                                                                                                                                */+ p0 n. y! A  A4 \* D$ d
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */) C/ |* P6 [% E8 u2 ?
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    ( Y$ x& R7 O4 i: d! r* Y! _
  190. /*                                                                                                                                                */
    . J5 M: }. S1 s5 f5 D6 N0 l
  191. /* Input:                                                                                                                                */* }2 v0 p* j9 Y
  192. /*                SO                                                                                                                                */6 f8 c2 O1 r. y- ]' _) c
  193. /*                                                                                                                                                */
    ; W; c6 y2 y7 ^3 F
  194. /* Output:                                                                                                                                */& Q$ g) m3 a  w* s/ X7 o
  195. /*                None                                                                                                                        */" \" S. o1 Y1 B, A" L
  196. /************************************************************************/: A0 E! L/ N/ S
  197. unsigned char Get_Byte()
    * A3 g; y3 g, q# y" R0 P4 }
  198. {8 |! Y- u5 P' w7 ~+ l5 b
  199.         unsigned char i = 0, in = 0, temp = 0;5 B; n( l; i1 i$ m. N% t, F1 t
  200.         for (i = 0; i < 8; i++)( Q* z+ W: I- W3 L1 a" V
  201.         {
    8 _3 ?1 S- o0 N* p6 @
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    % i" U$ q$ f9 Y# H; N- Y
  203.                 temp = SO;                        /* save input */
    ! O) z2 j" v( m$ A3 I8 O. F7 t% N
  204.                 SCK = 1;                        /* toggle clock high */
    . v- I# F; V7 n3 W
  205.                 if (temp == 1)                        /* check to see if bit is high *// g$ `5 J# E+ f+ F. U
  206.                         in = in | 0x01;                /* if high, make bit high */
    + z8 R& b. }& ^0 m

  207. 0 c$ y' W; \. W' c
  208.                 SCK = 0;                        /* toggle clock low */$ S! S/ B1 Y+ D# Z
  209. 2 j" V" C. E, f- e
  210.         }0 s4 B. y6 i8 P* |7 P  ?0 f* r- Y7 W
  211.         return in;
    4 \7 V3 G' @0 z3 B
  212. }
    5 M6 b) x! L3 o

  213. / w1 l8 G+ l6 j
  214. /************************************************************************/9 Z' @. F2 a: K! F  D
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    : O- [' [1 f' x9 F( R
  216. /*                                                                                                                                                */
    + P% b  V! M, C: P! n# ?3 @
  217. /* This procedure polls for the SO line during AAI programming                  */# a/ a% @6 v, o$ i6 E+ j) G
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    % Y$ z$ [9 i1 Q# Q2 r9 f; E
  219. /* is completed                                                                                                                        */6 I9 z$ X' ?& U. Y
  220. /*                                                                                                                                                */
    7 f' i2 Z! ?7 A: d2 j1 R
  221. /* Input:                                                                                                                                */
    & H3 _! }6 v! ]/ `! ]3 R8 k# R
  222. /*                SO                                                                                                                                */
    / A+ p% `/ }9 L/ @( @! `; Y
  223. /*                                                                                                                                                */
    $ g5 W9 H, n; T, j
  224. /* Output:                                                                                                                                */! R8 D" r3 k9 r8 n6 T! Q4 `3 y1 c
  225. /*                None                                                                                                                        */8 e5 z* H+ e: B3 r& v! ]! V$ c
  226. /************************************************************************/
    6 D( M2 Z* G+ q% T3 z
  227. void Poll_SO()
    & K' A1 c& N8 T; R+ \  @' V6 M
  228. {6 }" F% I( U  }5 d8 R  Q* [
  229.         unsigned char temp = 0;9 B7 a4 T, a4 T6 v% `3 H# k0 s
  230.         CE_Low();4 K, {6 z1 t" T
  231.     while (temp == 0x00)        /* waste time until not busy */& k( q) J9 F) _6 u+ N* L
  232.                 temp = SO;- d4 {$ D; w" ^2 ]/ \2 \! W
  233.         CE_High();) j8 ]7 c0 u, }& A8 [
  234. }
    $ B2 B; x+ |+ ^% S5 K
  235. 6 T" u  Z9 m4 h1 G1 H
  236. /************************************************************************/
    + \" H+ v, Q4 V" A0 v7 a' f
  237. /* PROCEDURE: CE_High                                                                                                        */
    2 L' K' B) F6 a/ q& O0 w
  238. /*                                                                                                                                                */
    6 k* o# i% X. q* O1 k+ T0 H  k
  239. /* This procedure set CE = High.                                                                                */
    / o( Z4 L0 t. ^
  240. /*                                                                                                                                                */
    0 H0 K2 B7 G6 y* f# `
  241. /* Input:                                                                                                                                */
    - v6 R" K7 Q; A  F' u( N6 Q. I
  242. /*                None                                                                                                                        */
    5 W, z3 I! l7 n' H
  243. /*                                                                                                                                                */; r! Y1 j" K  Y/ N& Y) e- X9 q; ~9 \
  244. /* Output:                                                                                                                                */
    7 u$ a; n4 z/ }- p) O$ T
  245. /*                CE                                                                                                                                */
    ( G# A$ y+ x! f+ X
  246. /*                                                                                                                                                */
    6 V* Y4 Y, ^, T7 M: i" q2 h# b
  247. /************************************************************************/
    + E6 Z" A& E0 n& N' G# U
  248. void CE_High()
    7 C! s5 b7 k7 O% m9 f
  249. {
    # T6 W& h' ?) U+ B0 y2 z" O
  250.         CE = 1;                                /* set CE high */0 i+ ?! t! o+ ~3 V  a: v
  251. }
    ' {9 w2 K' a) G& x8 s$ t

  252. # x* q. f/ A; }/ e8 z6 b1 x4 Z
  253. /************************************************************************/& i& L5 H+ g  [9 K+ T% ~6 g: C
  254. /* PROCEDURE: CE_Low                                                                                                        */' m$ x; Z8 h) L. s6 u* H
  255. /*                                                                                                                                                */5 N% [) d2 k2 T! t9 V
  256. /* This procedure drives the CE of the device to low.                                          */
    " P# U1 y3 M- `+ F# q
  257. /*                                                                                                                                                */4 d, ?, T4 |2 U% ~
  258. /* Input:                                                                                                                                */
    0 T0 x0 R. P' F4 F* C2 g' J
  259. /*                None                                                                                                                        */
    2 ?5 C) \7 N' v9 X
  260. /*                                                                                                                                                */: I' L, x0 \- D( O* q, N) m
  261. /* Output:                                                                                                                                */
    0 v0 ]- l. T# W2 ?
  262. /*                CE                                                                                                                                */! u  J6 g- o7 O: F) w4 @
  263. /*                                                                                                                                                */2 v9 G: ^9 N1 a2 `/ N2 w
  264. /************************************************************************/
    5 l- x# O8 `5 W; K7 {6 z- A
  265. void CE_Low() $ i, o2 l3 u9 n( d- p  Z6 D
  266. {        5 J- r4 _2 [2 y) t1 k
  267.         CE = 0;                                /* clear CE low */# x1 _: U0 a$ U6 l: p+ r
  268. }0 N) S9 {; n3 Y' d6 I% s( ?# ?

  269. 4 L& r; C" R. N7 V/ l3 q; Y, U5 j. F
  270. /************************************************************************/
    ) Z4 m- D7 \- ?8 Z8 t9 _) q: _$ @
  271. /* PROCEDURE: Hold()                                                                                                        */) q8 q  Q# C0 j* o0 H
  272. /*                                                                                                                                                */
    3 B/ G9 [% M; g/ p% V3 _: s
  273. /* This procedure clears the Hold pin to low.                                                        */
    : @! ]) ^/ w3 K
  274. /*                                                                                                                                                */
    + |& e% @" M7 I- l9 t$ J: `4 {
  275. /* Input:                                                                                                                                */: w" X1 Q2 B# ?
  276. /*                None                                                                                                                        */( h5 C# }! m: c/ n! r# O/ E6 _
  277. /*                                                                                                                                                */: O/ ]' \# q" K/ r
  278. /* Output:                                                                                                                                */4 i1 P: p" Z6 R8 r3 F& L+ r1 \
  279. /*                Hold                                                                                                                        */
    1 n; N; s( `0 q% N& S& W
  280. /************************************************************************/
      w% P0 h9 b, U: H* Q9 ?6 C
  281. void Hold_Low()
    3 [, f4 _1 i( |+ b' p
  282. {
    & z; |- u# U3 k; z$ c! _
  283.         Hold = 0;                        /* clear Hold pin */
    4 E6 I% e; ]1 L8 v8 x4 Y
  284. }" m, \! s6 j2 K: T% G

  285. " R( o3 P% v7 |- Q. V
  286. /************************************************************************// Y" B. N; Z+ \8 j4 D' @9 _
  287. /* PROCEDURE: Unhold()                                                                                                        */! ]- Z! k9 \2 M' G# Z8 I7 b7 [
  288. /*                                                                                                                                                */8 {* f+ l% }! [1 ]4 b: e( X# N
  289. /* This procedure sets the Hold pin to high.                                                        */5 g1 l9 X0 c) Z6 G, Z- S
  290. /*                                                                                                                                                */
    , x* J8 Z4 T5 e+ l# k2 b0 B
  291. /* Input:                                                                                                                                */
    ' `4 g6 V) I, y$ h* b' P- ?
  292. /*                None                                                                                                                        */: f0 i, l6 Y. }/ j' P
  293. /*                                                                                                                                                */5 Y# b0 e3 E/ ^0 S
  294. /* Output:                                                                                                                                */
    % p* C' X0 {6 u. v  ~
  295. /*                Hold                                                                                                                        */
    # Y$ \1 O* I; C7 q. C4 E( R
  296. /************************************************************************/% B! g3 s' s; k2 c4 l3 G
  297. void Unhold()
    1 N7 x1 ^+ k9 v7 t, n; ?0 n2 ?3 h
  298. {
    7 f- B9 c7 N8 p2 L0 \2 [
  299.         Hold = 1;                        /* set Hold pin */
    7 U4 K3 ?- t: {# O0 y$ }
  300. }
    3 F9 ~4 g% O5 V3 u0 Y

  301. : L+ b" S% f' o
  302. /************************************************************************/
    ( `9 |5 D( [1 D- A7 k
  303. /* PROCEDURE: WP()                                                                                                                */0 j! o/ A/ T. f/ E' E1 [
  304. /*                                                                                                                                                */( d9 K9 p( A6 `" }
  305. /* This procedure clears the WP pin to low.                                                                */
    5 g5 ]# k+ _( g% k2 _9 D
  306. /*                                                                                                                                                *// j# U0 `5 \8 h1 w
  307. /* Input:                                                                                                                                */
    3 @% x6 `5 \2 W1 S! I; h4 v$ M
  308. /*                None                                                                                                                        */
    ; x5 @; H2 R, C) o* n: Z* _5 l* Y
  309. /*                                                                                                                                                */; V3 g  _7 e+ h9 u
  310. /* Output:                                                                                                                                */
    ; \% F; m  @6 f* B
  311. /*                WP                                                                                                                                */
    " i: B+ ?) z  V: k9 s+ ~9 r
  312. /************************************************************************/
      U- ^, N3 L; u. ]9 Y! j3 `* s
  313. void WP_Low()3 S3 G9 C5 a* U& G% \8 y3 [
  314. {
    + t7 X( B; P( O. a
  315.         WP = 0;                                /* clear WP pin */
    - }- w' v  l: E5 T/ f+ k
  316. }
    - c+ E- e0 s7 p2 l, g3 A
  317. ( D+ j: J. V: W9 U4 _& w4 @
  318. /************************************************************************/. K3 [# J) J; o- N4 i$ f0 {9 \
  319. /* PROCEDURE: UnWP()                                                                                                        */
    2 I* B2 k7 o+ \% a" s* A
  320. /*                                                                                                                                                */) G3 _/ m+ w6 K1 }8 }; I+ Z" q# N
  321. /* This procedure sets the WP pin to high.                                                                */
    6 Q- ]( |* `) f, p- j
  322. /*                                                                                                                                                */4 r" S: |+ m3 ~4 @' a1 E" U
  323. /* Input:                                                                                                                                */
    2 ~/ P! w5 l+ X& p
  324. /*                None                                                                                                                        */
    + x) z& n0 B& l" d8 A
  325. /*                                                                                                                                                */
    % U5 m& P" {  u' |8 w6 H
  326. /* Output:                                                                                                                                */6 R* K. `  E$ Y. c$ V
  327. /*                WP                                                                                                                                */: w  _" @/ D# h
  328. /************************************************************************/- X2 W% @# H0 a% K
  329. void UnWP()
    / i* L/ B& r4 R3 f
  330. {6 a, o2 w2 S/ D$ V- L8 a1 F3 O; G
  331.         WP = 1;                                /* set WP pin *// a2 r- N6 K$ q+ q
  332. }8 l; a' I2 [/ k, C2 e6 O
  333. & E3 [8 X$ X# e% ~1 ^4 `$ q8 B/ M
  334. /************************************************************************/: G% ?. r9 S1 D% m
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    3 i, I0 Q( y7 W9 ]
  336. /*                                                                                                                                                */% o$ W/ H+ |% k/ S9 O& i
  337. /* This procedure read the status register and returns the byte.                */
    1 {' W9 P8 q& O; G4 s0 s* x
  338. /*                                                                                                                                                */
    % }. m' P* X* F4 |$ K
  339. /* Input:                                                                                                                                */5 S5 ?* M& [, k
  340. /*                None                                                                                                                        */
    / O7 P* ]5 g. l  J. J: P. R/ G
  341. /*                                                                                                                                                */8 d- E1 W- `, M4 s
  342. /* Returns:                                                                                                                                *// O$ H! S* y. o
  343. /*                byte                                                                                                                        */' [$ M3 p& }. U! n( k
  344. /************************************************************************/+ l; \4 h0 g& h( \; q
  345. unsigned char Read_Status_Register()+ s, P) ^! J5 w+ Z! d: H$ j
  346. {
    9 Y+ e4 q& a8 S! Q; w0 d" L- F5 o
  347.         unsigned char byte = 0;
    7 i" c# ?3 z2 p. t
  348.         CE_Low();                                /* enable device */; J+ K1 L9 [: X$ m9 H1 p+ k- P5 V
  349.         Send_Byte(0x05);                /* send RDSR command */9 q8 M$ a+ a5 S4 M2 K: d
  350.         byte = Get_Byte();                /* receive byte */1 w# E, {7 W: P6 x
  351.         CE_High();                                /* disable device */
    & M& w5 n4 m* \9 ^" S1 D# P
  352.         return byte;
    ) `( S8 P! h/ V9 [# j
  353. }% r$ h( h2 i0 U8 U
  354.   s* Y7 J! w( V  h$ t
  355. /************************************************************************/+ W9 Q' N2 \! y- J; z
  356. /* PROCEDURE: EWSR                                                                                                                */
    0 r# U, f8 C4 [. [& V
  357. /*                                                                                                                                                */
    9 o. `9 s, A' U6 N" \
  358. /* This procedure Enables Write Status Register.                                                  */; l5 e. I/ w8 D. w
  359. /*                                                                                                                                                */5 }2 {. a; g+ w9 \/ b* X  e# `; N3 @9 l
  360. /* Input:                                                                                                                                */' R5 _* ?9 ?* G% r# [! f6 Q
  361. /*                None                                                                                                                        */
    5 [9 y  N) z2 p
  362. /*                                                                                                                                                */' @* A* k5 M' g5 h1 E; u
  363. /* Returns:                                                                                                                                */' [8 I' }# H. `! o3 [3 F
  364. /*                Nothing                                                                                                                        */
    : X5 ?0 R/ T( m; U
  365. /************************************************************************/& M, m1 u2 o$ O2 j& T
  366. void EWSR()
    " ~" w8 K+ p8 j  U& y9 g0 Y8 \) A6 M
  367. {% r+ U6 _& N4 b% g
  368.         CE_Low();                                /* enable device */7 G) z0 y$ X$ z3 o6 C: X9 g2 O
  369.         Send_Byte(0x50);                /* enable writing to the status register */9 o  h6 z, \: G+ r
  370.         CE_High();                                /* disable device */4 M  @+ @! f+ A; b/ V
  371. }
    ' G! w4 F7 E- W  N

  372. ' X4 J  u' y# l- H0 m: p. y! X
  373. /************************************************************************/. C  R" A- a% c8 x8 A  c7 b
  374. /* PROCEDURE: WRSR                                                                                                                */
    6 e# t+ V  d4 R5 i
  375. /*                                                                                                                                                */0 t# }3 t& B: ?) ~: T
  376. /* This procedure writes a byte to the Status Register.                                        */6 B/ d& S  |, `
  377. /*                                                                                                                                                */
    7 O, y7 Y  r6 s5 p, g- U
  378. /* Input:                                                                                                                                */8 i! x* d6 Z  ?2 o0 L: F
  379. /*                byte                                                                                                                        */9 Y- n! }) g8 W" T( \6 M* m
  380. /*                                                                                                                                                */
    ) N* }) S0 V2 {/ K% f3 s1 d2 _
  381. /* Returns:                                                                                                                                */
    ! t% o9 y" A( u- G7 ?, W
  382. /*                Nothing                                                                                                                        */0 _' u2 U5 O* w# A" {
  383. /************************************************************************/
    , P% P- o& @3 q" K' p& @: |
  384. void WRSR(byte)
    ! J9 d8 v' L% t( K! O- y/ {4 l
  385. {
    / b% V3 Y/ q) p9 r7 G! W! }. w- ]
  386.         CE_Low();                                /* enable device */( ]5 [" I0 K* E/ ~# B) z/ Y
  387.         Send_Byte(0x01);                /* select write to status register */9 Y  I; F$ q/ L) u) C& j
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    3 I* b8 ]' S0 k8 [3 e" K3 [$ b/ m
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    ! T/ [0 X4 n1 \# l
  390.         CE_High();                                /* disable the device */
    ; a; l9 \" X" H
  391. }
    ! _4 z3 v2 N& M5 f) d
  392. & l( B1 o. C- [8 t* K
  393. /************************************************************************/
    * ^  J" m. I3 v( d3 H7 E) @3 G
  394. /* PROCEDURE: WREN                                                                                                                */- V1 @: O* I/ Z, }9 k- W" c
  395. /*                                                                                                                                                */
    4 S6 o" F' W. @9 V2 k- r8 O& y6 s8 W
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    * U* X9 \# v* ?: C5 G
  397. /* to Enables Write Status Register.                                                                        */  l5 |1 u5 x$ j( S
  398. /*                                                                                                                                                */
    * F; w( F3 X7 x6 k3 Z
  399. /* Input:                                                                                                                                */  D5 @3 _' E3 O7 R7 O: I; S- G5 W
  400. /*                None                                                                                                                        */
    4 M; t5 ?9 t1 }2 Y
  401. /*                                                                                                                                                */* s7 ], m: N7 A1 _+ `# j3 p
  402. /* Returns:                                                                                                                                */4 E, |& W. Y  X' k! B8 Z- m2 J/ `
  403. /*                Nothing                                                                                                                        */: I, U9 b" g8 h2 a
  404. /************************************************************************/( _! {: e7 p& y# o: g. m) A
  405. void WREN(), [1 m- a- s& J2 Q- S6 Z: @( w
  406. {
    " O2 ^# X: Y5 R# a0 C& g
  407.         CE_Low();                                /* enable device */1 L) S$ \5 ~5 G: [' e3 b; s
  408.         Send_Byte(0x06);                /* send WREN command */' J! O  f( A! K# a* u" K9 V7 G
  409.         CE_High();                                /* disable device */2 `- d/ U  |, ~# T3 K
  410. }7 R  U+ H0 T" ~  n2 a# r) r7 t3 B

  411. 7 h. p. a7 z  ]3 S8 }" Y
  412. /************************************************************************/. x5 c, i/ f( j+ K: h* R; T( i) i2 Y
  413. /* PROCEDURE: WRDI                                                                                                                */
    3 x8 c+ i: k1 P" R- h$ [
  414. /*                                                                                                                                                */
    $ U% \, ]. ^  d; v" {7 @) `$ i3 N
  415. /* This procedure disables the Write Enable Latch.                                                */
    3 U+ |/ E0 {# Z  g
  416. /*                                                                                                                                                */
    & X4 \, [+ r7 R# l7 {$ s$ z' u
  417. /* Input:                                                                                                                                */) I3 c( P1 s: |+ j- e% l  m2 q
  418. /*                None                                                                                                                        */
    9 _+ F0 Z, U/ h* b
  419. /*                                                                                                                                                */0 S9 n4 H; V! u$ H+ [
  420. /* Returns:                                                                                                                                */$ R/ r' J7 J3 y* m+ u
  421. /*                Nothing                                                                                                                        */
    : M; r% |" p  j( _+ c
  422. /************************************************************************/
    ) q8 V4 j& ?+ u0 l
  423. void WRDI()
    , o/ z: H5 Q0 s- [$ [) z; M
  424. {+ l1 A: N5 \% B1 c
  425.         CE_Low();                                /* enable device */
    / V9 ?/ h7 L. w
  426.         Send_Byte(0x04);                /* send WRDI command */5 u) t9 t5 t9 c% X: o- _
  427.         CE_High();                                /* disable device */
    + l9 t2 V1 @9 s* u
  428. }" Y; j. R" j" `, u0 I$ C

  429. 5 @- H$ P# |$ }) s1 a4 {/ `: m
  430. /************************************************************************/9 R, c5 S9 a& l6 y( }) @1 A
  431. /* PROCEDURE: EBSY                                                                                                                */5 A9 \5 Z3 _5 N) C; q1 B+ L
  432. /*                                                                                                                                                */
    7 k( i# }4 S8 r4 f9 b
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */: L8 j* J& N7 p5 M5 f3 E
  434. /* programming.                                                                                                                        */0 B0 z- i% O0 n
  435. /*                                                                                                                                                */
    1 {/ e, o1 q% q, Q4 l5 ?4 c
  436. /* Input:                                                                                                                                */" u4 s& h6 r* ~  F5 v  e
  437. /*                None                                                                                                                        */
    ) t1 h9 t( V) L( c, T8 _
  438. /*                                                                                                                                                */! x& V( g( o; Z  w
  439. /* Returns:                                                                                                                                */! w3 Y. D3 U2 s- w7 G" t
  440. /*                Nothing                                                                                                                        */
    $ ?' _0 D, e7 |8 |+ _+ q6 H$ }
  441. /************************************************************************/& c+ ]# K+ s3 z! |  I4 P8 D0 x
  442. void EBSY()
    / V; c9 L% p  Z" ]
  443. {- t; z6 _5 b; Z
  444.         CE_Low();                                /* enable device */
    " X5 l5 o  |6 B7 L/ V
  445.         Send_Byte(0x70);                /* send EBSY command */+ U8 D' k; r9 l
  446.         CE_High();                                /* disable device */7 q: S! l& [# @" a: X. X
  447. }
    9 ]9 m! W6 f! ~+ V% k' t

  448. % t  u/ S* g+ C7 B
  449. /************************************************************************// k7 \! n, g& q& r& }. q
  450. /* PROCEDURE: DBSY                                                                                                                */
    0 z4 ^: g& R9 K
  451. /*                                                                                                                                                */
    * Q. e! m2 d4 R1 z  Y( h/ |' g
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */; Y* T$ r2 N0 ^( h( \
  453. /* programming.                                                                                                                        */, h' w4 j7 S5 m" J$ L
  454. /*                                                                                                                                                *// `. J6 x! j% S1 _
  455. /* Input:                                                                                                                                */
    + T; F2 K( l! v" y) _3 W1 Y9 g
  456. /*                None                                                                                                                        */& W8 I. P# k* A2 s' I
  457. /*                                                                                                                                                */
    ; F0 V; y/ e8 t% Q; W0 c
  458. /* Returns:                                                                                                                                */2 h/ V2 I# H, j& [+ n
  459. /*                Nothing                                                                                                                        */! P; [5 Z% [( p$ D& h* m
  460. /************************************************************************/& j: E1 k9 C2 z& L& C, v
  461. void DBSY()
    9 o: f0 Y/ k  ^) o- o2 V& M7 g
  462. {
    4 [2 l$ o$ {4 f& h8 y& {, x5 x
  463.         CE_Low();                                /* enable device */5 l% l4 y% @/ i, Q% Z" v$ Y
  464.         Send_Byte(0x80);                /* send DBSY command */0 [& `) s$ [! u+ p& z
  465.         CE_High();                                /* disable device */5 |: |8 E9 R/ |: W
  466. }! }0 g* [7 E1 g) Z7 w

  467. . o+ U- M; G( G7 |  O* V
  468. /************************************************************************/
    ! L% B" q! T4 m& z/ c3 f4 O2 j
  469. /* PROCEDURE: Read_ID                                                                                                        */3 o" ]" y( n3 I3 p! X/ ?
  470. /*                                                                                                                                                */
    1 h/ @: D6 w! g0 |/ k; {6 F# r
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    6 [5 d0 p% F/ H* b
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */4 n) }4 p" t/ b' |0 q1 B( o
  473. /* It is up to the user to give the last byte ID_addr to determine      */- ?% Z' v% R0 R( R
  474. /* whether the device outputs manufacturer's ID first, or device ID         */- N$ ?5 T- M( R" r2 V2 t; j/ k
  475. /* first.  Please see the product datasheet for details.  Returns ID in */" i/ T, T, h# p7 Z( M9 H/ F: C
  476. /* variable byte.                                                                                                                */
    . O3 t4 B5 {. l/ H- j
  477. /*                                                                                                                                                */- P% Z; P) E* Z$ {/ `" N* A% a
  478. /* Input:                                                                                                                                */3 d7 L$ [; ^; M* j: R6 O, n
  479. /*                ID_addr                                                                                                                        */
    / N) h9 d" e* d( W
  480. /*                                                                                                                                                */
    9 i! j/ l& h6 Z- r! \
  481. /* Returns:                                                                                                                                */
    ; }! G8 N; o4 e1 l8 J! P
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */; _( Y# d9 g' @( `! ]1 s
  483. /*                                                                                                                                                */2 W4 P$ O( L7 Z- t
  484. /************************************************************************/
    * D2 ]! \" x  Q& E1 Y& t$ Q
  485. unsigned char Read_ID(ID_addr)
    / T5 P2 M6 X5 w3 P- Y
  486. {0 j* L0 H- M4 h- Y! C* A  ~
  487.         unsigned char byte;
    5 I' |: a* t' E  N8 r
  488.         CE_Low();                                /* enable device */4 A+ ^4 y0 d5 Q; v0 M
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    ' v* u, e. y/ ]: N
  490.     Send_Byte(0x00);                /* send address */
    " Z8 W; U* _2 B: S  w+ g
  491.         Send_Byte(0x00);                /* send address */- U: J  ^; Q- k% }* T9 u
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    # ^; }: T) T) \# L1 o
  493.         byte = Get_Byte();                /* receive byte */0 ]0 C. {4 C7 n4 C
  494.         CE_High();                                /* disable device */
    8 d! |3 f& d$ N. E' g6 K3 z% w' _
  495.         return byte;
    ; o' }) Y6 z/ C* Q4 f  v* d
  496. }
    ' i- ]& P7 \2 o( N+ z+ v
  497. / C" E: L" a. y# f& L
  498. /************************************************************************/$ m+ E: X* j' l) d; P. i+ ~
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    0 a& M- e! O5 F: B
  500. /*                                                                                                                                                */
    # ?4 ?/ b" o' X, W( n
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    ) F5 v- h, J. `4 U
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */& W/ N& R/ V% @) X4 P- C/ e$ f: w- K) v: H
  503. /* Please see the product datasheet for details.                                                  */5 y5 C1 r; V+ {" @) ^1 W( K. \* k
  504. /*                                                                                                                                                */- E7 c% N% L* Q) N, R
  505. /* Input:                                                                                                                                */- U# p3 `, ^. x# V# j2 b
  506. /*                None                                                                                                                        */
    , U2 w' r' ^6 i" J# D# g2 X% P
  507. /*                                                                                                                                                */
    0 B) T. z) ?( [! s9 K  ~0 ?6 L
  508. /* Returns:                                                                                                                                */9 B# z) c7 s0 d3 w3 Q
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    , ]% n" d  \! S! u6 n2 d
  510. /*                 and Device ID (8Eh)                                                                                        */
    ! h9 h; w" w/ j3 ^5 I+ _
  511. /*                                                                                                                                                */
    . {$ K5 Z9 b+ I% v/ w
  512. /************************************************************************/
    $ g' L" C! E  ]# i  W
  513. unsigned long Jedec_ID_Read()
    $ O" b9 E% ^4 v, y* K# E6 d: o
  514. {1 v1 F) A! u# [
  515.         unsigned long temp;9 e5 N, v3 ~4 }5 }- j7 \( [
  516.         & w" _4 @( t  I8 P! d
  517.         temp = 0;+ J* Y& N4 V, n0 K6 I+ q

  518. 9 N& j2 }& x( ^% \- r
  519.         CE_Low();                                        /* enable device */
    6 z; b4 r; e% Y
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */! G1 B, f9 g/ n4 S4 s4 Y, v: a$ g9 K
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    3 h6 e9 O( B$ T+ U
  522.         temp = (temp | Get_Byte()) << 8;        ; {! X, R6 M  p0 }
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */7 ^$ z' h( i+ ?. o
  524.         CE_High();                                                        /* disable device */9 a& O6 h5 Q+ U% t& b+ [8 F
  525. & R  i& J& d( Y+ v3 ~) y/ I+ Z5 W1 l( V
  526.         return temp;9 N3 W7 {& U, I0 k( D8 f8 g
  527. }' A) h. _3 {7 J- o* |
  528. 7 ~& T' R8 m  X1 N2 J
  529. /************************************************************************/( B, U4 p/ Y. `: \3 L0 J* \
  530. /* PROCEDURE:        Read                                                                                                        */
    ( G# l5 A8 j) W* l. M
  531. /*                                                                                                                                                */               
    ' i# V4 B- S! y" l: I
  532. /* This procedure reads one address of the device.  It will return the         */8 G" b) r* s( ?. E4 Y9 M
  533. /* byte read in variable byte.                                                                                        */
    & ~' u+ \) X. k6 I* {+ [
  534. /*                                                                                                                                                */
    ; V8 K6 i  R! n' u
  535. /*                                                                                                                                                */) ?) f( b: p9 k$ `4 h
  536. /*                                                                                                                                                */
      b5 w$ a4 j2 I& S7 Y
  537. /* Input:                                                                                                                                */
    , J* w& J9 j1 K8 l
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    * E( }" g0 f2 k7 q4 m# ]
  539. /*                                                                                                                                      */
    . o; g, R) [6 F2 I4 z3 n6 J5 ]6 k) ?  l
  540. /*                                                                                                                                                */
    . f' z' u9 V( r5 K, q2 o' y
  541. /* Returns:                                                                                                                                */6 F0 C1 P' S/ f1 u  I/ n
  542. /*                byte                                                                                                                        */
    ) R6 a' W9 q* Z
  543. /*                                                                                                                                                */
    0 ~% Y5 @# B- f
  544. /************************************************************************/2 N: P5 ^8 n: c7 p* v! V
  545. unsigned char Read(unsigned long Dst) ; i1 u  q. S: ~9 A$ T! T8 m
  546. {7 \  _; y+ N4 G: ?  F+ j4 ], U. |
  547.         unsigned char byte = 0;        , S' B2 S& s" R
  548. # S: W  ], G% c' {9 k1 s
  549.         CE_Low();                                /* enable device */
    8 J( u4 {& v/ {& u6 m
  550.         Send_Byte(0x03);                 /* read command */
    " R+ B/ D$ a3 [  _! f
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    6 \8 ~; ^3 {+ p1 E
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));9 D+ j+ o1 w# u& g  b
  553.         Send_Byte(Dst & 0xFF);
    . L7 C& C1 K5 M! M- j, F$ v
  554.         byte = Get_Byte();
    ' e$ A% \# u4 r& i& e" d8 G% Z  m4 {
  555.         CE_High();                                /* disable device */; ~2 `# b9 {8 _$ T" p/ m! s
  556.         return byte;                        /* return one byte read */
    " I1 F. Y: @0 y$ b
  557. }
    # W+ D0 f; E* ]: E6 G0 [
  558. - q4 j$ e6 Z( }* g# ~6 }
  559. /************************************************************************/
    7 t, K2 k5 B( B
  560. /* PROCEDURE:        Read_Cont                                                                                                */, _) I9 H- I( v. D9 H. i& f
  561. /*                                                                                                                                                */                / b$ @; k( b. ~% n7 |, J& |
  562. /* This procedure reads multiple addresses of the device and stores                */
    + [9 A$ b7 L9 x  V: i' S; T! L' k! _
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/: p! ~/ N( R9 [; C  T
  564. /*                                                                                                                                                */
    + g: r6 D: M% ~3 K/ i
  565. /* Input:                                                                                                                                */1 j5 H$ A( D. A% N1 P" n
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    1 Y! G. P: O! \; b) |- f
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    2 a& U. D1 s8 E3 ^3 c( ^; T
  568. /*                                                                                                                                                */
    # G7 j7 h! @6 L7 i
  569. /* Returns:                                                                                                                                */+ Y8 ^/ u8 ~3 p! a# J* p
  570. /*                Nothing                                                                                                                        */
    ( x% Y! {8 ]: u! ?  S/ \
  571. /*                                                                                                                                                */
    ) X3 g; b  }  M2 C/ [; ~! s
  572. /************************************************************************/0 L) I( H* `( `- l5 Z" x& _- ?' G
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    9 x: ~% f8 E; w
  574. {2 Z$ a: f' t- T) q
  575.         unsigned long i = 0;1 J$ V* j$ _4 u0 ^
  576.         CE_Low();                                        /* enable device */6 U6 X- h$ T6 X
  577.         Send_Byte(0x03);                         /* read command */0 r6 R6 Q9 M  ?( U% U6 E
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    - T  e5 C  L+ `. B2 {
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));7 N; E: }% K, p: Z
  580.         Send_Byte(Dst & 0xFF);9 N( S' F* m( X
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    4 ?; [# x$ G" w* d, v5 w) I
  582.         {( P4 E6 R% _) q6 R8 M6 J# u+ w
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    % G# `* O6 X9 o1 T+ v* D
  584.         }, N; U5 Z) e5 L: ^1 o
  585.         CE_High();                                        /* disable device */
    ' d6 j% C$ N# m, g9 d/ V7 E
  586. - f  o& o8 G0 n! g+ J; i, _9 V
  587. }/ D- s. b7 Z, [+ J5 ?1 c8 t+ t

  588. ( ~( J- H2 X/ m. w6 t
  589. /************************************************************************/
    " ^1 m" Y" O6 O8 G9 D# }# `
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */; ^! S% Z' x; R8 c( C1 v
  591. /*                                                                                                                                                */                6 j' P. H2 v7 _" ~# S  C, `6 c
  592. /* This procedure reads one address of the device.  It will return the         */
    . s7 ~5 F: L8 m9 p5 _  ^
  593. /* byte read in variable byte.                                                                                        */
    3 l7 a" {7 e6 W7 o# Q
  594. /*                                                                                                                                                */
    ! m* S/ P5 t9 K! s
  595. /*                                                                                                                                                */
    7 }; s* ?) T: J# H6 p
  596. /*                                                                                                                                                */
    & l: ]& S6 J1 I8 c0 Y) f: _% x
  597. /* Input:                                                                                                                                */
    4 r. o, k0 X  |3 Z/ a4 b
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    % s' }, q' c# N3 y7 D* i
  599. /*                                                                                                                                      */
    3 y1 Q, g! E$ G& b
  600. /*                                                                                                                                                */9 p) q, g7 O7 J
  601. /* Returns:                                                                                                                                */$ h+ \0 o0 P7 M! O; {
  602. /*                byte                                                                                                                        */
    ' M) \; |; ]3 X0 Y' h* V7 S, s& N
  603. /*                                                                                                                                                */
    : T& E- L) X, t- e5 J
  604. /************************************************************************/
    . Q$ x' k6 G7 b0 Q( R9 w
  605. unsigned char HighSpeed_Read(unsigned long Dst) # s2 v; U9 W' |* B/ j, m
  606. {
    1 z' C; N4 a$ R+ z* @+ m# G
  607.         unsigned char byte = 0;       
    . U" `  y+ E3 \/ Z& _2 M+ F
  608. - z! c' y& E/ v+ d- [
  609.         CE_Low();                                /* enable device */* J1 M! b( h: u3 c1 W
  610.         Send_Byte(0x0B);                 /* read command */
    4 c/ R) |, T5 I5 w  L
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    7 }# s% C7 h: x! ~/ W( B" i/ q
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));* P5 P* ^  {/ ]: U' n, w9 g
  613.         Send_Byte(Dst & 0xFF);
    ' T7 R' k/ [; _2 m4 f
  614.         Send_Byte(0xFF);                /*dummy byte*/% F. }( L2 {; g9 r% y/ U, y) w7 o
  615.         byte = Get_Byte();8 Q" `2 j5 q3 ?3 O/ [
  616.         CE_High();                                /* disable device */( h% G: f- r6 L
  617.         return byte;                        /* return one byte read */- E8 ?7 Y. X% B
  618. }
    2 g8 Y* S# O- e0 p9 V% Q" U5 _" H/ X9 w

  619. * {. Y% c- m1 a' k. |
  620. /************************************************************************/4 t% ^( y4 v- O
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */: F/ Y0 E6 [: f9 p; {6 z
  622. /*                                                                                                                                                */               
    7 J  g' q! e: }# k8 i
  623. /* This procedure reads multiple addresses of the device and stores                */3 I* D1 w2 B. J* N) J
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    " y# i0 ~2 f$ p1 E" c, \# F9 G8 S( A/ e
  625. /*                                                                                                                                                */
    & J4 `& y5 X" ?7 M9 W
  626. /* Input:                                                                                                                                */
    $ H! R& W7 R$ V8 J- n# Z
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    3 n0 A& H1 S; \) i1 f+ D5 V
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    # g$ H/ V, z' w' A- [; m. p- F6 L
  629. /*                                                                                                                                                */
      t; ~- K& H1 y
  630. /* Returns:                                                                                                                                */
    $ c9 o$ E4 {2 t7 J$ {+ {
  631. /*                Nothing                                                                                                                        */2 @3 e6 A& j4 z* ?" m0 {. Z+ G
  632. /*                                                                                                                                                */
    , E$ Q# v6 z2 y8 O
  633. /************************************************************************/
    8 m4 b9 B! k2 G2 ]4 j$ w$ i
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)& E3 e  [1 h2 c, W; M, m  P
  635. {# E) J: }1 X" L# S
  636.         unsigned long i = 0;  c2 B, z. q! r- s# k1 \
  637.         CE_Low();                                        /* enable device */
    / f% U/ \, K0 B+ b( N
  638.         Send_Byte(0x0B);                         /* read command */, q: F' O: X# t8 ^
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes *// f" W* o1 Y) S! x+ `/ z
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    / S) J' P! h5 l, y& W! u
  641.         Send_Byte(Dst & 0xFF);6 B- j5 O% @7 y* w# S9 f& e
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    * r5 o- W/ O6 N
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    3 G7 w5 y+ X7 e5 C
  644.         {
    1 {/ d0 e8 E  y) d6 l
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */1 i7 N+ H1 B- `% o& _2 q/ L
  646.         }
    * R" D1 D! u! k" d! L5 R7 e: q0 U+ w
  647.         CE_High();                                /* disable device */+ ~% J$ I% R5 M, H
  648. }# s0 I8 X# F6 }, e2 E

  649. ! M0 r& ]* `5 i  k) V1 {( W
  650. /************************************************************************/
    " Y6 i9 L9 V) E+ O5 f, s# G# ]
  651. /* PROCEDURE:        Byte_Program                                                                                        */' h" @0 y, A( X
  652. /*                                                                                                                                                *// T) J( l' y- Z
  653. /* This procedure programs one address of the device.                                        */9 Y6 u7 m: a' u! M0 v
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    ( ~4 e( L5 a! L# a, T% j. _7 q! _3 h) ]
  655. /* block protected.                                                                                                                */; }' [) Y9 M# a  v, n* C1 d8 e0 s* K
  656. /*                                                                                                                                                */9 ]+ L) R$ w( s% p5 ]/ V! _0 g
  657. /*                                                                                                                                                */
    . K3 D% p2 k) P# n+ I6 O! l8 b
  658. /*                                                                                                                                                */. x$ ~' z) }. T5 e- ?
  659. /* Input:                                                                                                                                */
    ! s9 {  |# f; ~" b) n' Q% U
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    8 D! u8 z$ q" P
  661. /*                byte:                byte to be programmed                                                                */
    " M8 P5 W1 [' ]2 ~
  662. /*                                                                                                                                      */7 i1 G: p- f2 t3 {7 b
  663. /*                                                                                                                                                */
    3 j3 t1 S; o6 f4 ]4 K  Z! ~
  664. /* Returns:                                                                                                                                */3 B" |7 }& W+ Q+ |% z( n
  665. /*                Nothing                                                                                                                        */2 k7 x! R$ P4 e$ p5 f3 M
  666. /*                                                                                                                                                */
    # M# h! `& g0 _
  667. /************************************************************************/. Q& g; T1 ~. u7 c0 ^, _5 ?' O
  668. void Byte_Program(unsigned long Dst, unsigned char byte)/ `6 F2 r$ \- i
  669. {
    ' q5 p& ^! m) u! V6 C
  670.         CE_Low();                                        /* enable device */8 J2 L! i  E% \' X- ]% D* ]
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    ) a4 \1 v4 U& o# ?
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */5 _+ Y, S4 E; U
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 R3 T8 h6 A# j1 e
  674.         Send_Byte(Dst & 0xFF);
    2 N. \3 s. v7 w. N% z# c/ w
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    * E+ [, V; E. _1 p2 Q
  676.         CE_High();                                        /* disable device */7 Y& d4 E' S  y8 Q- c- i5 s; `
  677. }
    ( N/ B9 w: r) `9 v/ ]! [5 Q
  678. ) d. h0 S* k7 p6 }9 m% Y2 X) S
  679. /************************************************************************/4 K; p! q3 b* T# E1 M) R' b) H0 w
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */) F3 K" t0 W5 ]7 G
  681. /*                                                                                                                                                */
      S; \: j  {& R: l/ S# P' S' e
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/1 ^' E. Q" r$ w+ j
  683. /* the device:  1st data byte will be programmed into the initial                 */
    + z9 `- E1 m, u/ E, z) g
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    6 a8 q& ?& I7 z+ X* E, e
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    % \6 `( P& x2 s6 }4 @
  686. /* is used to to start the AAI process.  It should be followed by                 */+ p) F  O/ \: n, ^
  687. /* Auto_Add_IncB.                                                                                                                */
    + h4 ]% T( O( g) O2 m
  688. /* Assumption:  Address being programmed is already erased and is NOT        */% F" P, {$ k9 F' L+ R. ~; m" ?
  689. /*                                block protected.                                                                                */, K% d' W( l5 D/ J6 Q) j/ |0 T
  690. /*                                                                                                                                                */
    " M# q' C( p# B- t) H
  691. /*                                                                                                                                                */
    , a. J) w0 n% H2 i' ]  o
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    ! Y1 z' c' ?7 @- I* S* G8 `7 X8 {
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    ; a3 S( l+ h7 n2 u0 _
  694. /*         unless AAI is programming the last address or last address of                */
    9 z; t$ ?5 [* O1 s9 |& M" f
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    4 ]5 Q. l8 u8 H& X- P6 d2 }
  696. /*                                                                                                                                                */
    , e4 d# e: t* T$ g1 w! b1 r
  697. /* Input:                                                                                                                                */
    / U. g8 l/ a4 L; s3 _. E8 C" M
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    - J- k2 J  ]  y' p
  699. /*                byte1:                1st byte to be programmed                                                        */
    9 b+ X4 X5 B( p  A3 i
  700. /*      byte1:                2nd byte to be programmed                                                        */7 H, K* y  t! g6 _. I
  701. /*                                                                                                                                                */
    $ ~, C6 G+ M7 U$ S9 y/ b/ s3 l
  702. /* Returns:                                                                                                                                */' g+ u) g; K, [8 m" A* t
  703. /*                Nothing                                                                                                                        */' q8 V0 g/ |/ z( C: H
  704. /*                                                                                                                                                */
    ; ?: A, a2 M8 y( N
  705. /************************************************************************/1 Q4 u9 h! P8 I/ a
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)3 p& f% r) R! K$ S* B
  707. {
    # E7 D/ m/ p  w1 z  M( ]; c
  708.         CE_Low();                                        /* enable device */# j- V+ ?3 A! c0 f, ]
  709.         Send_Byte(0xAD);                        /* send AAI command */8 k5 w  c% j% ]. v
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */  q: N4 l' {5 y2 }
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ! r, m; W) f! P2 @; S# o7 U
  712.         Send_Byte(Dst & 0xFF);* [  N+ \8 b4 Q: t( Z1 B
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    2 ], K: J. D  T
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    # X# ]4 A( j4 K% a
  715.         CE_High();                                        /* disable device */
    + |/ [3 z. t% d6 K/ [$ U
  716. }0 M7 _5 x! g( D$ ^7 b
  717. " g+ e7 Z+ o4 J& h
  718. /************************************************************************/
      B1 l. @, e# T" ~+ o9 ^0 h+ D
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    ; s0 I7 y8 P3 `3 j1 P# g/ A4 s+ T  Y
  720. /*                                                                                                                                                */  a+ n; |4 @: y3 u1 t
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    " a: s/ O2 o$ {2 a8 O
  722. /* the device:  1st data byte will be programmed into the initial                 */0 T+ d) s. n. D( o+ p
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */: o. x8 v; t1 h  I
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    : |% f. h0 d# f2 J! U; ?
  725. /* is used after Auto_Address_IncA.                                                                                */
    8 _% {7 `0 J. w8 X/ n
  726. /* Assumption:  Address being programmed is already erased and is NOT        */! m1 C+ Q" R4 y9 Z" i* V) Q
  727. /*                                block protected.                                                                                */
    # U9 @' a3 R: H+ H$ \
  728. /*                                                                                                                                                */
    # I# w4 X" q+ v( B# m5 j
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */7 D9 B. Y% X0 Z  }
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    1 }2 U3 h/ U- ~7 J* q0 E
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */- k& x1 f( B  T& d# l. v
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    ' ^  A: p1 Y" a# u  G
  733. /*         last address of unprotected block, which automatically exits                 */: |) W7 x4 d  K! T" N
  734. /*         AAI mode.                                                                                                                        */+ t# C0 {8 ~0 m2 _  U. g
  735. /*                                                                                                                                                */* N. `2 B4 \1 }$ L2 G
  736. /* Input:                                                                                                                                *// K5 m) w* ~* P9 N7 A
  737. /*                                                                                                                                                */4 W- ^2 P+ t' a. w6 ]
  738. /*                byte1:                1st byte to be programmed                                                        */
    " |9 a" Q3 T4 Y0 d; d1 e
  739. /*                byte2:                2nd byte to be programmed                                                        */
    : ^0 _9 d. N8 ?- g0 T+ _; c1 ^; R
  740. /*                                                                                                                                      */9 O  U5 k4 z/ i/ }  b5 L& l" Q
  741. /*                                                                                                                                                */
    + x, w3 t& _# K+ L6 }! y
  742. /* Returns:                                                                                                                                */
    - z  K* z. F+ U. I7 ]2 u5 `
  743. /*                Nothing                                                                                                                        */3 ?( {! |& k9 p- \* ~
  744. /*                                                                                                                                                */# h/ I3 U6 o! @4 |* B! z2 j( i
  745. /************************************************************************/4 K2 c5 k' K& o5 e- \+ y8 M
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)4 P! `  k4 f" u' ^% h2 t
  747. {
    . n: J& H! P) [! F5 T
  748.         CE_Low();                                        /* enable device *// `! j2 G/ [1 K
  749.         Send_Byte(0xAD);                        /* send AAI command */
    ' Q7 V& P$ L0 V+ p
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    , S. k8 I! \, K1 W9 ?. |1 t5 [
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    " l0 L% K/ `) g; q
  752.         CE_High();                                        /* disable device */
    + f( Z# p; `6 M: Z  `4 U! R
  753. }
    4 L+ g5 l2 z% g
  754. - [+ o+ k% E' Z- l( d& a; @! T
  755. /************************************************************************/7 F# q1 c# U8 a# ?
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    ' c" \# A5 _% ]) ?
  757. /*                                                                                                                                                */) B' S5 y4 Y6 @) }$ I( L# p
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    - Z. }! L0 Y; g. \2 F
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */& b% c. j  i, P4 Q
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    0 X6 I) P7 `2 c$ @
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */- r/ u3 ?/ x! y+ d" ^3 a
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    ! n8 B2 n* L$ {5 [' L9 f3 V: Q
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    . f3 y& @3 M& V$ ~6 K8 s' ]1 T% d; l1 O
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    # c! ?! |# H  i2 V- `  @3 h
  765. /* Assumption:  Address being programmed is already erased and is NOT        *// C! K3 {- f7 H$ e
  766. /*                                block protected.                                                                                */- e* {  N* Z7 d' K1 t2 L% j
  767. /*                                                                                                                                                */1 |+ s; V8 V2 l1 I
  768. /*                                                                                                                                                */
    . Q$ E" Y, M% L" D6 r5 |2 u( p7 `
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    5 d5 A) y2 v  M" B  W
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */- c' ~0 a" T/ m/ Z0 _
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    & I# I( N4 i0 P; z- \4 u: s( R) s
  772. /*          to exit AAI mode unless AAI is programming the last address or                */) F2 T/ D% _8 F1 C( ]
  773. /*         last address of unprotected block, which automatically exits                 */- w) G9 _/ l. l% [& H3 Q, w
  774. /*         AAI mode.                                                                                                                        */# Z6 b# P, R7 b0 W6 E, Q4 E
  775. /*                                                                                                                                                */  d2 G8 _3 I4 p; E/ c- E# U+ E
  776. /* Input:                                                                                                                                */+ r  ^) ?0 L4 |" l
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */0 c# K# E$ R! O6 h4 p: T, S/ Y
  778. /*                byte1:                1st byte to be programmed                                                        */! O5 y3 Y# l6 i  M
  779. /*      byte1:                2nd byte to be programmed                                                        */8 s+ t1 l/ {+ r; O
  780. /*                                                                                                                                                */" f  J. b# Q8 `" f: ^2 |
  781. /* Returns:                                                                                                                                */
    1 |* I+ g$ B: Y% J; O' x3 @
  782. /*                Nothing                                                                                                                        */
    4 O3 S  B. T: K- H7 d, u6 h+ F
  783. /*                                                                                                                                                */
    " ~" Y6 h* l% c6 M1 `
  784. /************************************************************************/" q) ?5 G5 g, O! D9 q1 F
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ! `. \# d4 O8 D* p$ d! V3 y& j2 }  O
  786. {( F& s0 H: r& _# ^( ]" D! @! p
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    5 b! @! I) h, ?, q/ n+ k" I

  788. . l3 I  H8 q: T% N! `9 B! C! i$ k
  789.         CE_Low();                                        /* enable device */8 [$ k- Q3 P! [5 v- V) I
  790.         Send_Byte(0xAD);                        /* send AAI command */
    4 m* Y- L* j4 H5 ?  X! Q
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    7 R1 `, R) d1 a0 `7 q# G9 `
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    * E" A7 x% Q' t" r/ O) g7 c
  793.         Send_Byte(Dst & 0xFF);+ U9 \2 [: f0 `3 F
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        . n" ~; `- ^+ r- v. M
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */( C# o& @) D0 ^* {0 w
  796.         CE_High();                                        /* disable device */5 t9 O0 v$ P6 q: r
  797.        
    , x- B: R: O$ `1 J4 l0 q. b
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    ; k" ?2 u3 K) R- e0 c/ T, e. R( {

  799. : h7 e' @  l, F% h1 [3 O& C. Q' P
  800. }
    ) H" L; ]4 U( l2 R* A
  801. % C0 I% w4 e8 b5 H
  802. /************************************************************************/
    + C$ E* l, N3 E3 h# h) b
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    $ ~6 e$ b" v; \) X  F
  804. /*                                                                                                                                                */
    " i4 k9 j& x; m2 p& O3 Y4 V! X
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */- M/ a  d. }* a1 w
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    6 r! R& c9 M" D8 M5 y, F; G) F9 R
  807. /* AAI programmming is completed.  It programs consecutive addresses of */9 {2 y% A% j* G+ N' A
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    , ~$ X) @5 f5 V. G1 t
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */5 l4 v' ~  X0 ]
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */, t, @, l6 `% s/ C
  811. /* used after Auto_Address_IncA.                                                                                */
      x- y+ ?- ?# @7 q) J+ V' R7 D$ s
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    ) e. s, z4 Y2 @+ R4 ^4 q- e& w
  813. /*                                block protected.                                                                                */. |9 v" l8 D. \% m* i4 ^2 t
  814. /*                                                                                                                                                */4 l+ q( {2 f. u5 N9 t  p
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */; A% {1 A% Z6 c
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 *// R# `3 o8 n$ w* j# J
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */# Y9 ^' p5 m/ J$ {
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    & n4 ^  F( U: n( w4 K% C
  819. /*         last address of unprotected block, which automatically exits                 */
    ) `$ w1 v- U3 c# d; O# @
  820. /*         AAI mode.                                                                                                                        */
    7 \/ I0 p  s- \3 [7 p! T
  821. /*                                                                                                                                                */
    ( m; m( w6 k, ]. x0 Z
  822. /* Input:                                                                                                                                */
    ( D$ _) B" C% f+ J0 R% ]! ~5 o
  823. /*                                                                                                                                                */3 t0 X. B5 G4 C) O3 E8 b
  824. /*                byte1:                1st byte to be programmed                                                        */
    1 x0 F* m9 ^% @& Q9 Z
  825. /*                byte2:                2nd byte to be programmed                                                        */; p% w4 c; K: Z9 d' A
  826. /*                                                                                                                                      */
    # _. X; p* H$ c) q' z0 \) M) V
  827. /*                                                                                                                                                */( Q' n5 A+ _9 l
  828. /* Returns:                                                                                                                                */
    $ u5 j9 I+ N) f  `& y' W) n
  829. /*                Nothing                                                                                                                        */
    - A3 _6 S1 o) `
  830. /*                                                                                                                                                */
    6 K+ D4 F; Q( w2 q- u4 p7 s
  831. /************************************************************************/9 e% E4 g6 D" ^5 q" b
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    5 A6 Y- t5 L: O5 o- t# E
  833. {8 E1 {2 K* X1 p$ d9 E0 j
  834.         CE_Low();                                /* enable device */
    % J' I/ k$ r  I$ D2 A' `
  835.         Send_Byte(0xAD);                /* send AAI command */
    4 ~$ r% o& J) z. {
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    1 r0 T" R* z) U5 t4 P( b
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    ' I" L2 f0 W) }6 X
  838.         CE_High();                                /* disable device */2 J; r2 M4 w  f

  839. ) n: l9 G* H" l
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    ) J/ H" b$ c6 d: n5 S) P
  841. * V( |% f- ]6 q  h3 s/ k6 f- {' _
  842.         WRDI();                                 /* Exit AAI before executing DBSY */# X3 _+ u/ W4 i3 z+ k0 }
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */- |2 l3 r- _! D7 o) G
  844. }- |' H7 B: g0 ^

  845. , Z" o+ |: _" |: t9 j" q( y
  846. /************************************************************************/
    ' Q% K5 L- }2 R) |) ?
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    3 C/ P, _/ D; M
  848. /*                                                                                                                                                */
    # ~( J$ `& `5 j5 b# L
  849. /* This procedure erases the entire Chip.                                                                */
    ' `; e/ `; k1 |5 l# I: c& l) C; K
  850. /*                                                                                                                                                */, n: r/ v- ?( R# v& j& ?  D
  851. /* Input:                                                                                                                                */7 ^/ n; I# T- O+ Y9 {* \5 P
  852. /*                None                                                                                                                        */5 ^, Y+ P7 i# u3 _; |# v
  853. /*                                                                                                                                                */
    : ]* {: L' o; ]3 D( G
  854. /* Returns:                                                                                                                                */, c4 K4 [: J) V* [9 Q
  855. /*                Nothing                                                                                                                        */7 t$ p: z6 U$ z* D, ^
  856. /************************************************************************/
    % n, S; K4 f' D' P8 ^  Y5 S0 ~
  857. void Chip_Erase()& b4 E+ x/ o* U7 T
  858. {                                                6 r5 E! ~6 A% L1 \! v
  859.         CE_Low();                                /* enable device */
    ; d6 ]5 `. ?( b8 k
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    % L8 _% O7 B( O3 s2 d' b, d
  861.         CE_High();                                /* disable device */' g6 B& q3 N# K7 a0 z" m
  862. }$ a; G2 N8 p- ~: S, @
  863. 3 [: Q8 Z) i( u
  864. /************************************************************************/
    % b9 J& D6 E: `- ]- `! E
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    9 i2 n# v2 M! Q" c; h. Q
  866. /*                                                                                                                                                */
    4 a  ~" _6 I, n! U
  867. /* This procedure Sector Erases the Chip.                                                                */* j: x- x  ~6 g
  868. /*                                                                                                                                                */" @3 X/ v7 u% j
  869. /* Input:                                                                                                                                */
    # P* q8 ?7 ?/ j) g: V
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */( |3 {7 i$ a* p
  871. /*                                                                                                                                                */
    8 p5 `) i" P3 Y$ H+ }1 O, L+ |
  872. /* Returns:                                                                                                                                */  T0 \, N, F# k, h8 q
  873. /*                Nothing                                                                                                                        *// e* v2 a8 N" L0 o7 J
  874. /************************************************************************/
    5 t/ b8 w' s/ T" g0 G1 n# \: n
  875. void Sector_Erase(unsigned long Dst)
    ! [5 r2 X; ~+ f3 \- h/ T! @
  876. {3 k# ~; m% `6 f* E! k  r; ~; _

  877. 7 m2 _" f! G. K5 p

  878. * g2 s' ~& Y0 |( z* K# P# G
  879.         CE_Low();                                        /* enable device */3 h: q: t$ @0 q; u
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    8 y. f0 V$ c) J/ r
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    # l& q# y7 T3 C& b7 v& N% _
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 D8 L/ Z) ^/ Q/ M
  883.         Send_Byte(Dst & 0xFF);
    / ]5 t" t( \; M! w- u+ a0 m& T5 z
  884.         CE_High();                                        /* disable device */
    , d; A) ], _9 S' C* i/ `
  885. }       
    % ]6 ~: u/ R2 e6 ^
  886. 6 D6 C+ x! Q2 p7 i1 T
  887. /************************************************************************// F" ?' x' Y( I9 g* X
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */1 ^% I" ~$ V; \# @- w  p! [
  889. /*                                                                                                                                                */" O+ G5 M4 [8 s  |) @) z
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */  h2 }+ t  D+ c0 ~4 h: t- D% g
  891. /*                                                                                                                                                */
    8 d) Z3 j- C& v8 w" x
  892. /* Input:                                                                                                                                */1 Z" R6 W' a# s) [5 D+ g* N+ M
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */) A7 h% a1 C) n8 t1 @- C
  894. /*                                                                                                                                                *// y5 t2 y4 ?3 v6 B# c  C$ }
  895. /* Returns:                                                                                                                                */, K7 D+ i1 s9 \( p
  896. /*                Nothing                                                                                                                        */
    4 n# r5 [3 v  W3 N+ z9 W
  897. /************************************************************************/1 o7 H" v$ e0 U( S: M
  898. void Block_Erase_32K(unsigned long Dst); G/ M; H  x' p' c
  899. {% y1 V6 s! c5 {4 P2 d" X
  900.         CE_Low();                                        /* enable device */8 J0 N: G( o% g$ S# q
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    2 M% f! P) |5 A
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */1 y# B' e8 e! N, u
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " D! g; [2 e3 [' a9 b- E# P3 O# @( B
  904.         Send_Byte(Dst & 0xFF);( m! d+ G# @' r5 f
  905.         CE_High();                                        /* disable device */
    . ]; f/ T. _& Q4 @. _
  906. }
    1 L! ~. F7 p8 p' C
  907. ' d' S6 j- s5 {8 M' k4 V1 p
  908. /************************************************************************/) G' C8 Q* d& r) R# o, @# Z
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    8 P6 i! {6 v) x4 J
  910. /*                                                                                                                                                */
    ! h3 W* V3 Q9 Z, b% A3 y
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */; W) M: u$ D% ]+ r
  912. /*                                                                                                                                                */4 N, ^- L' A! p# G% |( o6 Q
  913. /* Input:                                                                                                                                */
    # s, d% U. _0 H$ U# ]8 U
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */% a4 I# l  I* c
  915. /*                                                                                                                                                */: q, D8 ?/ @/ {* ?: [4 J
  916. /* Returns:                                                                                                                                */7 v. q' U3 p$ V! X
  917. /*                Nothing                                                                                                                        */4 P  t% _1 G+ w2 h& s) o& @
  918. /************************************************************************/0 T5 A: O( h) ~  J+ b# `
  919. void Block_Erase_64K(unsigned long Dst), j, A; |& ^) @+ ~+ U
  920. {
    8 M7 c8 h( T7 ^$ a  a* |- K# K7 L
  921.         CE_Low();                                        /* enable device */: E$ f( \4 M( x& ^; L6 n1 c
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    . i  [( E! }6 E* c) v9 b. _+ A% {% g
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ; u$ A# J# u2 m
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));6 U$ G7 p0 e# v+ t
  925.         Send_Byte(Dst & 0xFF);3 L- T+ y* X6 G3 r, u& g
  926.         CE_High();                                        /* disable device */
    " |6 p5 L- k+ i0 L; P! O
  927. }% Y" |' |" a; E) U" i8 N, W

  928. . n" o3 f/ E9 x2 N1 y) d9 e: l
  929. /************************************************************************/
    5 R4 v( y% e# m: C9 t
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    6 _' Y: H: W' y% L8 {
  931. /*                                                                                                                                                */
    - C( G' a. K! J. o
  932. /* This procedure waits until device is no longer busy (can be used by        */
    2 P' G4 W1 ~8 P0 `. k) {7 L
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */% Y1 H% U/ h5 P' ^: e& r
  934. /*                                                                                                                                                */4 ^2 k" W$ J( p0 ]  N# |3 t( o
  935. /* Input:                                                                                                                                */
    . l4 s' k! V% ]2 X+ }" Y
  936. /*                None                                                                                                                        */* `5 U1 z& R$ }6 H: C
  937. /*                                                                                                                                                */
    * C% ^( w" V- o6 N+ W
  938. /* Returns:                                                                                                                                */
    $ w) @: Y2 V& L  i  H( E% x
  939. /*                Nothing                                                                                                                        */
    8 q& p5 ]' k8 d
  940. /************************************************************************/7 K- |7 C6 R) e( X+ X
  941. void Wait_Busy()
    1 _- g7 K- |4 S7 k
  942. {" p3 ]- h6 E. y) g8 n7 d3 ]
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */, L& l7 N/ L3 ~+ t$ ^$ n5 D1 n
  944.                 Read_Status_Register();- Y- p! m9 o9 v; Y) O* e
  945. }
    6 ]4 H: j# \! M7 O8 e5 n) w
  946. " H# p& v: L& Z
  947. /************************************************************************/
    0 u" d+ A3 L" w, v3 z5 v
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    8 R$ ]) w1 h& }# f" y( g* o' c  n' S
  949. /*                                                                                                                                                */
    ! C4 E& A# O8 m5 Z% n, o
  950. /* This procedure waits until device is no longer busy for AAI mode.        */7 M7 K, e$ C; V+ \/ v- n! u# P
  951. /*                                                                                                                                                */
    4 O& x2 o$ ?$ n/ B, F
  952. /* Input:                                                                                                                                */
    + g  W) I8 u! M0 C; f  f
  953. /*                None                                                                                                                        */
    . W: y" z* d" T: Y
  954. /*                                                                                                                                                */$ s& n- J' [9 |7 d1 a
  955. /* Returns:                                                                                                                                */
    8 n& q* y+ U1 A# G2 ^( S
  956. /*                Nothing                                                                                                                        */" [- x4 o! V, m* _/ d
  957. /************************************************************************/
    1 [2 D% ~5 ?! S0 t( a
  958. void Wait_Busy_AAI()6 N- _$ P/ u" ~+ ~' h
  959. {
    : I8 K& x2 {. W) q( z
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    # h$ w! B: ?, E0 f
  961.                 Read_Status_Register();
    ) Z- t* A5 M) G8 c4 _, B6 q, m1 C
  962. }
    4 D1 D# N1 Q; d8 I, l1 t
  963. $ I" |9 a( B! G6 d: w9 L& k
  964. /************************************************************************/
    - w: g( v9 T; w
  965. /* PROCEDURE: WREN_Check                                                                                                */
    4 @( V( j9 f& ?' k9 W
  966. /*                                                                                                                                                */
    ; V0 l3 h6 V6 e, J* H# l
  967. /* This procedure checks to see if WEL bit set before program/erase.        */; f5 f6 A+ U9 g5 N6 k) j
  968. /*                                                                                                                                                */
    . p! _! K5 e% X
  969. /* Input:                                                                                                                                */
    - V0 @9 Y! i! P) H2 J
  970. /*                None                                                                                                                        */: l4 y; {* T& [" n& d( Y: y
  971. /*                                                                                                                                                */
    7 E* u3 Q% d/ ?- j' v, Q  k
  972. /* Returns:                                                                                                                                */
    , y7 S& S" O0 D, R8 K9 s
  973. /*                Nothing                                                                                                                        */
    2 |8 D( S) c! J0 m: @. }& U0 g
  974. /************************************************************************/7 Y- K  A) R/ D2 B6 m- N. K7 @
  975. void WREN_Check()
    : n# r. T- x: M  b) a+ \
  976. {' b* M! H+ @/ w5 z0 H$ g- ?
  977.         unsigned char byte;
    / a" V" z/ o% E/ d" x
  978.         byte = Read_Status_Register();        /* read the status register */2 S4 J) q  u' g+ @3 p, n
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    & \  C  y8 f' M& C; f8 h: m" p% z
  980.         {
    3 O, D* O, |) t5 |# v
  981.                 while(1)
    ; @3 }& O( t4 {. I# _5 Q* z! p, W# q
  982.                         /* add source code or statements for this file */: [! f: E' @4 h; m8 k) _" }: P
  983.                         /* to compile                                  */) N" L- E' E$ w7 @" _; R
  984.                         /* i.e. option: insert a display to view error on LED? */% Z+ Z4 S) B% O3 F. \4 Y
  985.                  
    % @8 `- l1 z+ z4 V# S3 B( b. e0 Z
  986.         }5 C7 I* s/ m# ], j  m
  987. }
    " p( D! i3 e+ s# e7 L1 ?

  988. 2 q: q, X. Q# z' V
  989. /************************************************************************/
    & I" K6 M4 K: C
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    0 v0 c& h1 j* g1 R
  991. /*                                                                                                                                                */* s" T; d6 U' y/ I) a) K/ M
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */0 w; ?9 g6 Z% X. R+ H. w. ]) y
  993. /*                                                                                                                                                */4 D8 W+ R8 z/ ~& X6 a' m- P) A
  994. /* Input:                                                                                                                                */
    & z# S" \( }" w$ k7 @
  995. /*                None                                                                                                                        */( G1 t4 b/ G; Q9 [
  996. /*                                                                                                                                                */& R! z4 Q8 e3 s% G: W* f3 E* Z
  997. /* Returns:                                                                                                                                */; Q' q2 {5 T" `( a7 n# ?
  998. /*                Nothing                                                                                                                        */6 [6 X, j* z' C" ~2 ^. t' C
  999. /************************************************************************/3 |5 _& X! U& S: c/ F
  1000. void WREN_AAI_Check()* a' a) V2 X7 [" q
  1001. {( m7 F7 e9 s5 f5 Q% k' x: i0 c
  1002.         unsigned char byte;+ S, G3 W' {" s4 C) c: ?9 l! C( f
  1003.         byte = Read_Status_Register();        /* read the status register */; i+ S) c3 m8 m% b5 r3 n6 {
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */) F6 T' M9 A' E! X& F$ [5 ?
  1005.         {
    $ K7 `4 K6 r  ~! w. j( P
  1006.                 while(1)                & i' O. t( g5 i2 Q% i5 Q* D  U
  1007.                         /* add source code or statements for this file */( s% \  O- R8 u& }
  1008.                         /* to compile                                  */8 s- _) `. c* i: R( Z+ Z
  1009.                         /* i.e. option: insert a display to view error on LED? */4 l- P1 @, A: b1 ]' r1 R  N3 D% Y( G

  1010. ( D, J1 D! n8 \' M. i% {6 a
  1011.         }
    . @: v, H+ P# q/ t
  1012. }5 I. o/ d7 T1 P& ~% r: E, z/ v
  1013. / v7 c* \& v# M) \
  1014. /************************************************************************/
    / x; @/ x4 i& b4 b# x
  1015. /* PROCEDURE: Verify                                                                                                        */  X! A$ \; a% R) I0 U
  1016. /*                                                                                                                                                */& U, x1 q; X  p
  1017. /* This procedure checks to see if the correct byte has be read.                */1 j4 |+ I: v8 g& M) q
  1018. /*                                                                                                                                                */1 G* O9 I/ R) t! Q' ?
  1019. /* Input:                                                                                                                                */0 q0 m3 M+ l# K6 w
  1020. /*                byte:                byte read                                                                                        */. ~; I# U4 t: Z' O8 F
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    0 b* x/ {- d6 `. l7 `& Y& @; P
  1022. /*                                                                                                                                                */
    - z2 q( ]. ^; D
  1023. /* Returns:                                                                                                                                */" a' @4 L0 e+ J2 F
  1024. /*                Nothing                                                                                                                        */6 Q- G. Z9 r. C, k: ~8 p/ r  P
  1025. /************************************************************************/" `' a3 q4 w/ E) M
  1026. void Verify(unsigned char byte, unsigned char cor_byte)% Z" Z" y! S) i# L
  1027. {
    / J6 u" c& Y' g9 G5 G
  1028.         if (byte != cor_byte)% g* E1 i: i. }) L
  1029.         {
    . r& X& [+ \* Z) b# T4 g
  1030.                 while(1)# n/ D, ^* J* j8 A3 E0 M5 _
  1031.                         /* add source code or statement for this file *// f( n' B1 `, w
  1032.                         /* to compile                                  */
    $ J4 t( ^% p- p/ Z5 L
  1033.                         /* i.e. option: insert a display to view error on LED? */7 O5 [2 y+ t, Q- g7 ]' t8 O; }. s) v9 [) h
  1034.                 : S4 u4 `" Q' O' j
  1035.         }
    , g8 R1 q, h7 g5 j) Z. R
  1036. }: s" Q; a: O/ G. y

  1037. % s0 f. f2 _7 d: s

  1038. 9 h% S/ u* G# f' u3 Y1 v* c
  1039. int main(): O! _) S) l; E6 X2 w; `
  1040. {5 a7 I1 L, R  Q/ j/ B6 c2 \

  1041. & Z' Q6 e  Y& X2 x
  1042. return 0;
    . O, Z1 p2 _& w% ?1 k3 I+ S
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:$ b3 H3 s+ e2 N0 j
   main()
* b/ h& Q: u- \+ z   里面怎么是空的呢?2 p+ E  E4 f( c8 ~0 V. K
   发一份给我吧' m7 `! `! D8 X# I+ @
mail:luyijun2005@hotmail.com
: I* t. Q. M, \# p. V- s  O, i咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
/ ~3 E7 A, N2 r+ @  P5 C9 M/ D# T0 m/ K8 }3 m
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。; G1 h  y: b$ V0 @  o
EC的代码在哪跑,你看DS的说明,每个EC都不同的。
% _, a' A9 R( d8 Q2 T/ N0 gOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
6 ?0 q% a! X$ Y) U: M! F0 A. O上面几个问题是你没看任何东西而白问。" a. I+ W) \% s* p/ N
1 ~: e, d) B" ^* Q& U0 y8 F1 S4 [# g
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。- X" h3 k3 Z" Y, u
. c6 |" P6 d4 U- z+ y
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
; F4 h' T& T1 e* G7 A# p2 `# H: Z- d: _- w5 n# v0 {  v
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
: h* j- ^4 }2 q" ]1 f
% H1 F' z0 u( T( S! b) e8 S. e关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...( j; t) j/ W# W7 S1 V- _1 U, Z) L

6 o3 h* z# s" J) o不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样" e8 B, x* L$ F  L4 i
似乎要把SPI能support 到最大,这EC chip应该有好卖点
5 H5 O6 u$ {0 h# ~" \9 R  V$ S. uBIOS功能要不要强大,也就决定了SPI Flach的大小7 a: o7 `( ?6 t" w. ]% M% H
我是这么想的~让OEM去决定要挂多大!, z+ B. @- F5 H; n4 f
如果我司有BIOS工程师就好了~哈
* H6 e! U. u! \& }; g7 D: @WPCE775应该算很新的东西,来看它支持到多大?
: l5 R9 F! K5 O' F( Z5 ]5 C2 _" v) O1 _& m% F, h
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte  g+ C: C' U1 y" M  k  z8 P
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.4 ~9 S$ O9 S, w' i- @. B5 `- B

" P: a$ Y; n* ^+ d这份driver收下~希望以后有用到
0 o+ }9 f- w3 k0 i7 H* N( b+ Q谢谢bini大大/ u0 V: }" I8 r# ?7 Y! H6 J3 X
: Z4 ?6 h  j  M0 T  `; l/ a
很新很新的新手,如有错误请指正 (准备看第二家的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()
0 q- ~( R" s& P7 G' j# \4 O3 i7 s4 j{: p6 p% D2 U. e" B3 p$ \
        unsigned char temp = 0;( u4 N+ k  C& s9 M* f
        CE_Low();$ o" e9 q( W1 z6 J. q$ P
    while (temp == 0x00)        /* waste time until not busy */" `5 e6 h1 x+ {7 a. e6 V" L( @
                temp = SO;
( i  j7 M' [- P% V        CE_High();; ~$ [- J. R7 p- R; N
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
$ p: ]/ J+ t, t{
8 K. L$ t* ?. \: k# `' r        ; z1 c2 ?$ |; ?* s
        unsigned char i = 0;) M1 E' V( k* F: F" d- v) c
        for (i = 0; i < 8; i++)
) r5 o2 `% k3 `- O) E        {
, Z' d& K- d. F6 Y  c                ( v6 B1 a7 ~; ?! }% d  R0 {
                if ((out & 0x80) == 0x80)        /* check if MSB is high */! ~" i& F1 I3 [4 W
                        SI = 1;
$ ]5 y8 k: s. s7 ^                else. ~( g$ s' ^7 ?- e( p; m" p
                        SI = 0;                                /* if not, set to low */
% L( L9 D* s' T& `% j+ f 问              SCK = 1;                                /* toggle clock high */6 B: l+ r1 ^. O8 f* r& X
   题            out = (out << 1);                /* shift 1 place for next bit */, K5 D9 a+ |8 ]& e$ j1 a
                SCK = 0;                                /* toggle clock low */( ]' a7 \0 t9 C* ~1 r
        }# C  b' T- ^8 y- c& j
}
5 G: e& _  W# p: p9 F" X 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-12-21 15:27 , Processed in 0.062077 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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