找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54189|回复: 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; T6 n" L* }% F9 f# N

  2. & Y, M1 C5 T' l! m  ]- {- w$ M( D
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    ' K; M5 |+ ?# w
  4. * A8 W# g0 L0 \/ r5 X& U0 Y2 c
  5. November 4th, 2005, Rev. 1.0* z/ Q' e+ ?8 C; |9 o

  6. # x1 z  j4 x; N; _4 A3 v
  7. ABOUT THE SOFTWARE' V. x% W& ~& {7 [1 ]# d
  8. This application note provides software driver examples for SST25VF080B,
    - v9 W) F' v; O+ T0 I
  9. Serial Flash. Extensive comments are included in each routine to describe
    6 B& S& ]( x9 t% z
  10. the function of each routine.  The interface coding uses polling method 2 f/ ?! T1 r" R9 V. F" O
  11. rather than the SPI protocol to interface with these serial devices.  The
    2 J. y5 U  R" e0 N# `
  12. functions are differentiated below in terms of the communication protocols* b& q6 ~- F' ^
  13. (uses Mode 0) and specific device operation instructions. This code has been 7 i/ m/ {" ?9 i( l/ S# C/ K
  14. designed to compile using the Keil compiler.1 F( \, q( j8 K6 k( v% `

  15. " Z! v- `  n" T" L( n
  16.   j. Q+ P7 B; T& Y
  17. ABOUT THE SST25VF080B" t5 \2 g, z/ k- R4 W

  18.   L2 L# ^6 e8 q, `; U, E5 P8 g6 k; Z
  19. Companion product datasheets for the SST25VF080B should be reviewed in - F3 D; r4 K2 N" K
  20. conjunction with this application note for a complete understanding ; p0 ^; Y7 @* |" V) ?9 a$ U5 g
  21. of the device.$ W- q- a- S5 M: `+ Z5 F& a+ J9 A. G

  22. 8 u- _3 p/ g# T

  23. * Q, O7 c/ q/ I3 Z, p2 T' g
  24. Device Communication Protocol(pinout related) functions:
    * r4 t1 P$ R( p0 `4 J' S

  25.   \! ^. j; o3 r/ Q) b5 t+ o9 j
  26. Functions                                    Function
    6 f8 I9 z5 Y7 Y
  27. ------------------------------------------------------------------
    4 u# o6 L* A  v3 t, {
  28. init                                        Initializes clock to set up mode 0.
    / e& L: s8 k, u& R4 [
  29. Send_Byte                                Sends one byte using SI pin to send and
    . V! d/ F0 S0 I& e
  30.                                                 shift out 1-bit per clock rising edge: E8 e& k4 b3 z1 x+ r# C$ T( F
  31. Get_Byte                                Receives one byte using SO pin to receive and shift 2 o2 Q4 h2 A; U
  32.                                                 in 1-bit per clock falling edge
    5 X# j: N7 @1 c: p+ `$ t7 z" c4 I0 c2 Z  d
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    ) P  E: ]$ Z& h6 p: @7 n$ E5 Y
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high. G8 N" C) V5 n# u" m
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    + [/ R/ R* T3 v8 x3 R/ A
  36. Hold_Low                                Clears Hold pin to make serial flash hold; \' D9 e* l* B4 _+ }
  37. Unhold                                        Unholds the serial flash/ D4 X2 r7 ]1 ?8 t% R4 u8 @
  38. WP_Low                                        Clears WP pin to make serial flash write protected! F6 i3 ~: E( w$ c* |5 T, \
  39. UnWP                                        Disables write protection pin. L) t. W7 I$ g
  40. 2 ^" y- W7 t  @, o0 j
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    0 P, p- w* m) {6 V9 c. k
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your- o. C- a6 [, o
  43. software which should reflect your hardware interfaced.          ' j- [! P/ P7 U' c( L; W

  44. 3 B  P6 M8 A% z

  45. ; c( f: L! O4 e, X* a: ~* _5 g/ A
  46. Device Operation Instruction functions:
    * \; X: ]$ ]5 h. g9 w
  47. 2 o8 g- T9 p3 Q4 f- P8 z) B. t6 ~; \6 C
  48. Functions                                    Function! a" P, [! H$ {& o
  49. ------------------------------------------------------------------
    ! Y/ F) K; M2 d! _7 V" K
  50. Read_Status_Register        Reads the status register of the serial flash
    % X) L: |: F. T3 h
  51. EWSR                                        Enables the Write Status Register
    # z# k$ A8 b* T
  52. WRSR                                        Performs a write to the status register
    4 ?1 H: j6 G% W% j' @
  53. WREN                                        Write enables the serial flash2 t3 }; R/ i2 M( R) c& h- S1 @
  54. WRDI                                        Write disables the serial flash. n/ _. _" }" w! n
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    / E, j4 A  j* c  e3 z( G' _3 ^- E
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming: a. {0 F7 b2 S
  57. Read_ID                                        Reads the manufacturer ID and device ID( ?& g/ r# o% C& [! R$ i& A
  58. Jedec_ID_Read                        Reads the Jedec ID
    : p! D$ W/ W" S# W. g8 M( Q
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    . v( D+ C$ p5 H
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency), ^7 y3 k& r2 |
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    6 {& [3 Y7 y* s' M$ t* N' ?9 c
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)7 Y1 V1 w  Q8 e
  63. Byte_Program                        Program one byte to the serial flash) y0 z" H# r  G. C
  64. Auto_Add_IncA                        Initial Auto Address Increment process8 A" V; O) l3 T3 @5 H. p2 r2 S' |
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    5 Q7 _; u. [; c! x4 ]# B0 L
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY1 p: f. e3 k* Z( Q
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    + A, Z. D9 W! K( J# S3 o+ p" l- u
  68. Chip_Erase                                Erases entire serial flash
    % c+ `# y0 u5 C. b
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    + n. l( Z1 Q9 A3 [# t  H) r: h
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash3 K7 \$ }/ c- [1 k/ Z
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    . |9 j: U) A: j0 c, A& ?4 c
  72. Wait_Busy                                Polls status register until busy bit is low8 O3 p1 `8 n0 \1 m. |0 V1 m# s) u
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    - h. h9 H9 {& ^# c& {7 l
  74. WREN_Check                                Checks to see if WEL is set
    ( {1 J+ l4 v& R, H+ j) ~
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set# _* A3 r& R# t8 g

  76. 1 w! b0 O$ h! f/ S; K

  77. ; s# ~" z" u! F% f8 c# k

  78. 6 [+ m1 k# h3 Y* y/ [
  79.                                                                      2 j+ J. U* k. h
  80. "C" LANGUAGE DRIVERS 7 }* a: q. G- o5 [* j: o
  81. % F: K% p8 R1 w) w/ s4 ]
  82. /********************************************************************/  ?- Q7 D% G' S( _2 P+ r
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */* ]) d5 J% L- a/ {" J
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */5 s6 _) h" n6 [9 _1 g
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    . X7 r2 ^6 K* U" F5 }6 v6 _
  86. /*                                                                  */$ l, H  w) Q8 f) y5 H/ I+ S, u
  87. /* Revision 1.0, November 4th, 2005                                                                          */   9 F5 o  V4 D$ A9 Z
  88. /*                                                                  */
    0 n) {1 C+ u- G
  89. /*                                                                                                                                        */
    8 p% X9 p) A8 J4 ]( F+ u, x) ^
  90. /********************************************************************/4 g$ z% ]2 s/ ?  a1 R6 z5 L% \2 H
  91.   W: n( d% I" W% l! U0 q$ R0 Y
  92. #include <stdio.h>
    & M0 w. G0 J2 q2 q& c# C8 G. a" C, u
  93. #include <stdlib.h>9 f$ v7 J" R; u

  94. - v- ~9 K) F* F
  95. /* Function Prototypes */7 c1 G; h" w. i" _  A" ~
  96. 4 ^) h5 q  Q9 a6 a0 l! c& ]
  97. void init();( K- K7 k: Q  c1 S1 S
  98. void Send_Byte(unsigned char out);
    3 L% D& F. Q2 K, H; b% \
  99. unsigned char Get_Byte();* e; o7 P, ?4 w9 _
  100. void Poll_SO();: }7 ]* K# P( e& v8 A. r
  101. void CE_High();' s, g7 r/ E) B7 m
  102. void CE_Low();1 n4 K# U1 \# P( _- r
  103. void Hold_Low();$ j( ]0 d" |( w3 w8 |4 f
  104. void Unhold();
    & b- {: L5 p1 l# I7 T" ~! p# M4 D
  105. void WP_Low();
    0 s( U  G; Q& R7 O
  106. void UnWP();( ~0 M+ r8 K; e) T
  107. unsigned char Read_Status_Register();
    1 }, z* }/ h: a+ C2 d0 C$ c# _# x
  108. void EWSR();5 I% l  I1 S- b& z0 h& r$ [
  109. void WRSR(byte);
    6 T- @4 v3 Z4 U% q- l. Z. X
  110. void WREN();, W: Y3 P8 c6 L5 i% G; k: U
  111. void WRDI();- y5 f( ^. t# G7 T
  112. void EBSY();% p  G6 N2 u& ^& g: u! {! I
  113. void DBSY();
    1 E1 v% o- d" n
  114. unsigned char Read_ID(ID_addr);
    " s" C0 ~. N; ~8 e; N
  115. unsigned long Jedec_ID_Read(); $ M: H( ?3 D9 }2 A
  116. unsigned char Read(unsigned long Dst);7 ]- J7 U. p/ n' a6 Z8 C
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    . x* z' M5 N9 p+ w  x; c( C0 M
  118. unsigned char HighSpeed_Read(unsigned long Dst); ( v6 I& J" X, J3 W7 v& K
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    * F! ~' ~0 s  y1 g1 `! r
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    + G0 D0 L* u7 Z7 a2 q; ~
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    # d) C, h2 T& Y+ d$ H
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
      M. V+ c+ S) x, ?1 {0 S6 a
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);& [( d' x) p. S0 x
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);& O! G; T6 l5 M# l( d+ U/ M! R
  125. void Chip_Erase();. y4 Y! Z/ z  B% E
  126. void Sector_Erase(unsigned long Dst);$ K- ?" a/ j. o
  127. void Block_Erase_32K(unsigned long Dst);% [8 }9 i  i4 Y& v$ w/ O
  128. void Block_Erase_64K(unsigned long Dst);* o1 T; C6 ~! z: W- E
  129. void Wait_Busy();
    1 ~- u1 n2 ~1 o) h- ?! O
  130. void Wait_Busy_AAI();
    ' w# [1 f/ X5 t/ b# c' A" I3 q
  131. void WREN_Check();" R. E) Y! v4 _. _
  132. void WREN_AAI_Check();, v5 u6 W( ?  d9 c% W; B% ]$ o% h
  133. 2 D" e( d* l2 L
  134. void Verify(unsigned char byte, unsigned char cor_byte);! v& I: i& F$ n6 o

  135. ' n8 ?% z7 Y4 ~6 }
  136. unsigned char idata upper_128[128];                /* global array to store read data */: n7 s* {0 {9 `8 a+ P% P
  137.                                                                                 /* to upper RAM area from 80H - FFH */: N4 q% Q% W7 }1 q& L+ I* E0 |, _

  138.   R* _" d9 e7 A1 }1 J/ [
  139. /************************************************************************/
    1 C) `+ ?; J" o, ~; ?3 |
  140. /* PROCEDURE: init                                                                                                                */, q6 z( P+ R3 u1 G
  141. /*                                                                                                                                                */
    % Q. P! f8 S8 |9 y% R
  142. /* This procedure initializes the SCK to low. Must be called prior to         */" B$ O4 V; X9 T# t4 r$ V
  143. /* setting up mode 0.                                                                                                        */2 n; {" [0 {1 e& j+ t& c
  144. /*                                                                                                                                                */
    0 L3 t; V. m% }6 X
  145. /* Input:                                                                                                                                */2 L% P% Q3 B6 a' u* F" ?4 k8 w* k
  146. /*                None                                                                                                                        */" k# G! d: F3 P6 n7 w' ^
  147. /*                                                                                                                                                *// S! R( `9 i9 A& f7 y' x, l
  148. /* Output:                                                                                                                                */
    0 r4 v, n9 `( s8 [. b' X1 U
  149. /*                SCK                                                                                                                                */3 E+ J5 l- G4 J8 ]: o" e9 X
  150. /************************************************************************/
    * w( N, A/ Z* F7 J2 n
  151. void init()8 `. _. }0 E% {0 d6 T
  152. {
    ) E! u5 s4 T- C0 [7 w
  153.         SCK = 0;        /* set clock to low initial state */& p/ H8 A9 R/ [  O
  154. }4 F5 x; `0 d5 D
  155. ! N5 v6 n+ N3 ^. Z5 x
  156. /************************************************************************/
    / Q, ~, e" Y- _( e
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    * R8 {( _$ b# i* a' ^: s1 r# s3 ]
  158. /*                                                                                                                                                */% Z) a6 z" E4 N7 M0 N7 s
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        *// g, Y* M+ g1 U' U
  160. /* edge on the the SI pin(LSB 1st).                                                                                */; K3 r% b( V7 L+ q7 B
  161. /*                                                                                                                                                */
    - x2 F4 o. e/ ]5 Y8 C
  162. /* Input:                                                                                                                                */
    ! C- A& I% W* S9 z+ V' }
  163. /*                out                                                                                                                                */- S: a/ r. J3 @. h7 N0 M8 T) L, S
  164. /*                                                                                                                                                */. g" F% c; b& W" G- X0 q) @3 V  _
  165. /* Output:                                                                                                                                */
    . L5 d( x. m) g7 z7 c
  166. /*                SI                                                                                                                                */
    / g% g0 B( I7 {; V0 z) L" S
  167. /************************************************************************/3 I' _  v6 J6 M8 F. S  a
  168. void Send_Byte(unsigned char out)
    # h) P! J% W! c8 p; F' e4 T: Y: D
  169. {: ]+ l& P4 ]0 x9 f9 K
  170.        
    6 h' {# S* K2 Y
  171.         unsigned char i = 0;+ S0 ^" @" Q$ ]$ w4 j+ R
  172.         for (i = 0; i < 8; i++)7 b% L: p- a7 W) p
  173.         {
    " N' P9 R& v( q' T) S, z7 c) i
  174.                 0 E1 b* l5 Z$ l, z
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */! X: z& o8 q* s  w* J: g
  176.                         SI = 1;
    5 a- H, ~% x  [9 ?
  177.                 else6 R4 n0 F* F$ h/ g
  178.                         SI = 0;                                /* if not, set to low */7 k8 o" `  U9 E1 _# }9 v
  179.                 SCK = 1;                                /* toggle clock high */
    ) b: u  W' u7 J/ l
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    . B  p  ?% ?& h3 J# ~# C
  181.                 SCK = 0;                                /* toggle clock low */+ X7 M0 }. T( {
  182.         }, N) q1 L7 a. r: ~3 r  q5 n. S8 e
  183. }
    0 x; {; D9 L$ `+ @4 {- R7 w4 X5 ~
  184. ! u) ]- }* Y: R3 x5 J- k
  185. /************************************************************************/; c9 ?* Q& G$ d" O" {! i$ u+ _+ [+ f
  186. /* PROCEDURE: Get_Byte                                                                                                        */! J) D. {( F, h7 y, Z, H  N7 V
  187. /*                                                                                                                                                */( D  Z/ o9 Q0 q& I2 _; r4 `
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    ! ?$ J. e. t6 E7 I6 B  T
  189. /* edge on the SO pin(LSB 1st).                                                                                        */) z+ {9 x6 N+ D# j1 J- ?% F
  190. /*                                                                                                                                                */
    ; Y6 I  V' e1 p# W5 s/ T
  191. /* Input:                                                                                                                                *// _* U8 m# p; I+ [8 Y+ w! m
  192. /*                SO                                                                                                                                */$ ]# a  a( q  T. t+ W8 ^7 J
  193. /*                                                                                                                                                */7 A7 W) Y- A/ z4 j1 Y1 e6 k. e: e
  194. /* Output:                                                                                                                                */
    9 R" e2 Y7 |* K
  195. /*                None                                                                                                                        */7 F4 z) G: p, k+ e- p3 b9 P
  196. /************************************************************************/
    ' d$ K- e1 |( C- _
  197. unsigned char Get_Byte()
    + u0 C: q: m% O4 c* F, T* @1 M
  198. {: I! w* q' B0 x3 x, I
  199.         unsigned char i = 0, in = 0, temp = 0;& t2 e& Z8 A5 P  I
  200.         for (i = 0; i < 8; i++)
    / `$ M! F$ d4 i
  201.         {
    $ J1 S$ n4 Q/ y+ T0 Q! f
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */, D) V* l$ N2 g. G4 l% k
  203.                 temp = SO;                        /* save input */: t) v0 y6 j) D' ?8 Z" X) K! }& Y3 X
  204.                 SCK = 1;                        /* toggle clock high */
    6 x2 a# K( I; }
  205.                 if (temp == 1)                        /* check to see if bit is high */7 i3 t$ f. \5 G7 c' u3 A: Q# u5 L
  206.                         in = in | 0x01;                /* if high, make bit high */
    3 u4 b4 V$ z+ T6 I( y
  207. 8 i0 }; o4 |: q. ^# c; {5 h
  208.                 SCK = 0;                        /* toggle clock low */
    % u# V, J( ?- }/ E" P

  209. 9 h7 s: L! j1 R* B4 }2 C
  210.         }
    7 H  F8 G$ T; Q1 h. J7 _$ c8 H: o
  211.         return in;
    ( b* L/ j+ p" j9 n4 y6 X
  212. }9 n3 x% ?% \$ h/ R, P& M

  213. 4 Z  B$ ^8 C2 [
  214. /************************************************************************/' k" t- @. g7 a/ [; e* o9 A) M* d% c
  215. /* PROCEDURE: Poll_SO                                                                                                        */& D, w9 r- ^2 n& `
  216. /*                                                                                                                                                */' W7 T* c/ E4 O- N. i# h) H. ^
  217. /* This procedure polls for the SO line during AAI programming                  */
    4 {" a- u- a0 d; j4 W# h2 q
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/% u/ V" {% x" Q1 M" k$ G  Z, m' Z3 ?3 }
  219. /* is completed                                                                                                                        */, o; U7 V0 R$ F: n$ `
  220. /*                                                                                                                                                */6 T/ @, q' y4 x& O* A
  221. /* Input:                                                                                                                                */
    & m9 j& Q, x/ i% N6 C9 z6 @
  222. /*                SO                                                                                                                                */; `4 K0 I6 U  w
  223. /*                                                                                                                                                */. ?4 Y) w, C7 J/ A5 q; L# v
  224. /* Output:                                                                                                                                */+ m! N3 n0 w$ O5 I* R
  225. /*                None                                                                                                                        */
    : U1 W2 o$ q" m: g
  226. /************************************************************************/- m( |. A2 X2 F/ s
  227. void Poll_SO()* q5 M3 e. G8 ]9 l8 t. ]* v/ F7 K
  228. {4 Z# I6 D! d) |% o! u$ W& Z. [. h  @; d
  229.         unsigned char temp = 0;
    ( O  m4 ?' ~$ W" b! D  J- z
  230.         CE_Low();
      l4 @, j: v/ u+ |% ?- W8 `+ v
  231.     while (temp == 0x00)        /* waste time until not busy */
      T+ c1 I0 T' H$ e' P% |6 K
  232.                 temp = SO;
    + j  a4 y$ O9 P# T/ M
  233.         CE_High();
    ! l3 x3 j* C. U1 i' g. F
  234. }
    8 b: [) O8 _' F- B" c7 F
  235. & a' o5 {( H6 _
  236. /************************************************************************/; ^, k3 J2 ?- `3 q6 W3 [
  237. /* PROCEDURE: CE_High                                                                                                        */
    - n0 |3 R* `% D+ h8 g0 m  }5 Q
  238. /*                                                                                                                                                */
    + M- ]' N& _! n1 l& p2 l* t
  239. /* This procedure set CE = High.                                                                                */
    / ?& J2 F: ~; E; c. \$ i5 V8 T
  240. /*                                                                                                                                                */
    $ U& _! J" c8 J' R* j7 C1 k8 Q4 I
  241. /* Input:                                                                                                                                */: C' c5 t6 S  ~5 o2 l
  242. /*                None                                                                                                                        */
    $ F3 X# k4 }" {- k1 l
  243. /*                                                                                                                                                */) s  U% g* p0 @, D0 a* V; y
  244. /* Output:                                                                                                                                */, e2 R& [/ v$ z  m, M! }+ z3 `
  245. /*                CE                                                                                                                                */
    9 c0 x( ]* E# W5 m* K
  246. /*                                                                                                                                                */
    1 U  b3 K9 }2 H4 ?$ ^2 b
  247. /************************************************************************/5 V8 ~1 \/ o* H  d( i
  248. void CE_High() 8 T5 r+ H! U8 d7 h3 Q
  249. {( s/ u! s- {1 ?1 t/ ~! o# s( t
  250.         CE = 1;                                /* set CE high */
    % B8 |( q* i3 H5 l% p
  251. }
    # t1 O! _- v, E+ U

  252. + M* i* o: a- F% N7 ~
  253. /************************************************************************/' C* X- [* v: ^2 S
  254. /* PROCEDURE: CE_Low                                                                                                        */
    - q; v& N  d- s0 f2 w/ b
  255. /*                                                                                                                                                */
    ' \9 G: C# U$ V! G" E# l  I6 f9 }+ S- x8 a
  256. /* This procedure drives the CE of the device to low.                                          */
    ( M/ ?: G( A# b2 E/ c; l
  257. /*                                                                                                                                                */" D4 {9 K- ?, T. A$ P& y2 X, @; F
  258. /* Input:                                                                                                                                */
    9 R" S; h" D: y5 o
  259. /*                None                                                                                                                        */
    ( `' ^5 J* E& k
  260. /*                                                                                                                                                */' |2 O( z7 `/ Y; a/ P& u. G
  261. /* Output:                                                                                                                                */. i" p# c- H+ ?- H
  262. /*                CE                                                                                                                                */
    5 t6 ?; ~4 V" j/ A' e* C
  263. /*                                                                                                                                                */
    . p) u) }; G$ ^( M9 I
  264. /************************************************************************/
    0 u$ g! x3 ?$ Y4 |
  265. void CE_Low()
    : ~7 c! b) ~9 w$ m
  266. {        9 B( N- [  s, s3 Q
  267.         CE = 0;                                /* clear CE low */: o% U6 {- z0 N
  268. }0 E0 e) Q) |9 H: Q  P6 V
  269. ' S$ H3 b; A* Y. _
  270. /************************************************************************/, p  {2 z+ o  N( z  L* G8 M
  271. /* PROCEDURE: Hold()                                                                                                        */3 d( O. C8 e! h6 N" W# v9 T- {
  272. /*                                                                                                                                                */
    ; q  _! ?9 @7 k( M. I  L
  273. /* This procedure clears the Hold pin to low.                                                        */
    9 b0 \; Z; F5 I$ E. O) r. R3 n% }
  274. /*                                                                                                                                                */8 |* o$ j6 X! y! }
  275. /* Input:                                                                                                                                */
    : D9 u7 V) B$ _3 n$ H5 u6 C/ J
  276. /*                None                                                                                                                        */
    9 I# S# H6 ?% [+ t( ^* a
  277. /*                                                                                                                                                */% g: G2 ~, D7 e
  278. /* Output:                                                                                                                                */# v% G3 l8 ~( I% P/ g: u9 K0 w
  279. /*                Hold                                                                                                                        */. v$ _2 i" b4 W- e
  280. /************************************************************************/3 O& Z$ Z% b+ _9 V$ F8 L% X8 C
  281. void Hold_Low()" f! b) U* N" _6 _
  282. {
    0 [; G9 Y& G8 g: B5 @
  283.         Hold = 0;                        /* clear Hold pin */* G' v! B3 f  ]3 H! J( b/ t
  284. }
      x  V$ |+ j! U, r" O- t0 Q' T

  285. / ^% N7 ?. E- Q
  286. /************************************************************************/# f. z0 }7 X. V9 ^4 `
  287. /* PROCEDURE: Unhold()                                                                                                        */" S+ }# j6 S+ ]! f
  288. /*                                                                                                                                                */4 B* Z$ B8 O2 w! u* d
  289. /* This procedure sets the Hold pin to high.                                                        */6 \8 g9 V5 ]+ H) x* J! C% I. w7 B2 X
  290. /*                                                                                                                                                */% E! M9 d/ I" {# x* ]1 e
  291. /* Input:                                                                                                                                */
    / c9 a* t# `( D6 z5 f
  292. /*                None                                                                                                                        */
    6 |' ~) d& F) D! J" G0 P' k
  293. /*                                                                                                                                                */
    7 K. F! g& P  s+ t& D
  294. /* Output:                                                                                                                                */- e3 |( b* g! r* S6 W
  295. /*                Hold                                                                                                                        */
    : r$ r8 U( r1 q" n3 R4 |$ A
  296. /************************************************************************/
    5 W, |+ T6 @  |2 ]' j; w/ Y8 q
  297. void Unhold()
    6 U2 O$ _8 |; K, {) G3 |
  298. {6 O" D) Q2 {: `% f# O1 f
  299.         Hold = 1;                        /* set Hold pin */
    3 U/ y; R0 z- I; B# ~
  300. }
    1 z- K( [: D& ^1 C; Y8 t2 I

  301. 3 I) l5 a2 @! }2 U. U7 @
  302. /************************************************************************/9 F1 O* [6 s! t0 c+ V: O$ M
  303. /* PROCEDURE: WP()                                                                                                                */
    1 ^# e/ g1 C/ h) r6 K
  304. /*                                                                                                                                                */
    9 _: \1 ^% i7 G$ P6 v8 o! a
  305. /* This procedure clears the WP pin to low.                                                                *// T2 q. N5 Z) a; h( r9 }
  306. /*                                                                                                                                                */
    # k* {0 \' z$ c; g- B4 y& ]* U3 t
  307. /* Input:                                                                                                                                */
    ; z5 ^2 N2 j9 R; \7 l; a
  308. /*                None                                                                                                                        */% f, ?5 x& o) _  J% s6 R
  309. /*                                                                                                                                                */% E1 B! N) L4 H( D" c+ v% E
  310. /* Output:                                                                                                                                */
    ! _9 C' F6 I, W2 d$ X6 ?2 G+ \* [
  311. /*                WP                                                                                                                                */
    9 Y( F8 d  b3 D4 d
  312. /************************************************************************/
    7 k4 X: ~0 x  c( O
  313. void WP_Low()+ I6 B: m+ S4 w. u' N
  314. {! B( i% Q1 e: q" K# t2 {, k/ Z
  315.         WP = 0;                                /* clear WP pin */
    , i9 w  ~/ ~6 n9 }8 k! O4 ?
  316. }
    0 b' w2 f3 O6 D& s* ?8 s! e* Z6 E
  317. * R7 j/ o/ G1 a, O7 M
  318. /************************************************************************/
    % [0 f) V& `" Y) u. C
  319. /* PROCEDURE: UnWP()                                                                                                        */- Y& _* S/ `( B- j0 @6 E
  320. /*                                                                                                                                                */
    ( r7 N  X9 B/ X( x' q! M. D
  321. /* This procedure sets the WP pin to high.                                                                */
    4 J% @8 F( a2 S1 e5 G. ?0 Q
  322. /*                                                                                                                                                */
    3 I6 A2 N  T" z2 M
  323. /* Input:                                                                                                                                */
    3 }8 Y$ i; t# ?$ f. T  {2 U3 Z" V
  324. /*                None                                                                                                                        */
    2 w! j3 `  b. f- }7 z4 r
  325. /*                                                                                                                                                */+ S! H+ h$ u, {
  326. /* Output:                                                                                                                                */1 f$ H+ R# b% F; \7 s* [: o$ p+ |
  327. /*                WP                                                                                                                                */
    % F% r8 A8 J! G$ q9 n5 b
  328. /************************************************************************/  q7 e" B* [& c% p9 o- F
  329. void UnWP()
    4 T0 G6 R+ K6 B/ v8 x7 n3 c1 M
  330. {
    8 {+ \3 z) x" u) s$ G1 B: k
  331.         WP = 1;                                /* set WP pin */1 t: Y9 [8 Z$ t( s
  332. }
    - v; L! J1 e' F7 P( D$ U: n

  333. + ~  M  l9 q( K" u9 _4 v/ B5 e
  334. /************************************************************************// x0 z6 ]( K9 `( y1 Y  ?7 i5 W
  335. /* PROCEDURE: Read_Status_Register                                                                                */# I  _$ D- \5 o' z, _8 Q
  336. /*                                                                                                                                                */
    4 G) M! G& ]) _8 e8 s! D0 o
  337. /* This procedure read the status register and returns the byte.                */
    3 w( h# W7 V" C9 p& s, }' e+ j
  338. /*                                                                                                                                                *// S5 b$ B6 h# C
  339. /* Input:                                                                                                                                */' s- w2 \, P) _+ J- A8 d# W
  340. /*                None                                                                                                                        */
    0 e( N& b! `; d2 u
  341. /*                                                                                                                                                */' k( [& V8 m: g
  342. /* Returns:                                                                                                                                */& J/ K6 N- r) T5 w
  343. /*                byte                                                                                                                        */& T  [1 z4 H; c0 J! l
  344. /************************************************************************/# {) T# c! C- J' M4 J
  345. unsigned char Read_Status_Register()) w% j1 _4 O- v; b2 l% H; C
  346. {& q$ g9 E5 @. b9 y
  347.         unsigned char byte = 0;
    0 }% ?2 n" n* e5 Y$ Z
  348.         CE_Low();                                /* enable device */* k; ?) @; U6 f( d$ v; d
  349.         Send_Byte(0x05);                /* send RDSR command */
    % L& V3 {& i% X: \
  350.         byte = Get_Byte();                /* receive byte */6 k: T% `, }& ~) O* ~
  351.         CE_High();                                /* disable device */9 Z: T/ C( A, A  x" w+ K
  352.         return byte;
    ! F0 m( r; {( n) i1 n5 z! O5 s3 R) M
  353. }8 C. C3 E4 w$ R0 S6 K. m

  354. / L+ X7 r3 ^! m& e3 A  C
  355. /************************************************************************/) n0 _- v; m  O& ~" T/ x
  356. /* PROCEDURE: EWSR                                                                                                                */
    / p3 N; k  x7 Z! N) C
  357. /*                                                                                                                                                */
    ( I8 L* r) k) k8 q
  358. /* This procedure Enables Write Status Register.                                                  */
      N, f- v6 v9 i! _
  359. /*                                                                                                                                                */
    5 q$ t# P+ s$ @6 Z
  360. /* Input:                                                                                                                                */6 o: W: r: O; s* k$ M; [5 v
  361. /*                None                                                                                                                        */% L7 l/ }) n1 _8 q; A$ o, U
  362. /*                                                                                                                                                */
    ' B  B9 L6 c" j- ]$ S# D% |
  363. /* Returns:                                                                                                                                */
    # P4 d# z8 l' S0 V/ f' _
  364. /*                Nothing                                                                                                                        */
    # \( r6 f7 k0 V: p: R* U
  365. /************************************************************************/- g2 G4 z8 N# m* C( ^$ e
  366. void EWSR()
    4 y; |& @. a8 F% P$ G
  367. {, x% B# R3 N% h# l
  368.         CE_Low();                                /* enable device */
    0 A9 ^3 d; C2 ^( {3 i6 K4 Z
  369.         Send_Byte(0x50);                /* enable writing to the status register */+ V& J5 p8 t8 }
  370.         CE_High();                                /* disable device */
    8 Y* \0 f7 `& N- j7 D) D
  371. }
    1 h) B$ }, q+ ]

  372. # V2 _! `& Q5 \* x5 I. O
  373. /************************************************************************/
    # l" N/ ^0 t) B! ~7 \! z/ _$ ?
  374. /* PROCEDURE: WRSR                                                                                                                */) T" T8 H: J2 M
  375. /*                                                                                                                                                */
    . G- j3 J4 H0 e
  376. /* This procedure writes a byte to the Status Register.                                        */
    & _- a! k, k" |$ L5 W
  377. /*                                                                                                                                                */
    + F" b- ]4 U- z: u* i4 X- l/ @" K& r
  378. /* Input:                                                                                                                                */
    9 {8 w9 C1 T. c& b+ Y+ `$ k, k
  379. /*                byte                                                                                                                        */( q# k7 D. Q8 Y+ w3 P5 T
  380. /*                                                                                                                                                */1 u; A+ b5 m! U0 x
  381. /* Returns:                                                                                                                                */4 l  B* k$ y# J( N2 f0 k6 U
  382. /*                Nothing                                                                                                                        */
    1 f* O. i* l% w* U. G' P
  383. /************************************************************************/7 R1 A: w+ T# `
  384. void WRSR(byte)
    0 Y3 e' l1 T. P! I  ?) u
  385. {
    $ o$ @9 s& R: t& I$ W: ^3 b0 b) K% i
  386.         CE_Low();                                /* enable device */" p* U- _. A# y! z/ r
  387.         Send_Byte(0x01);                /* select write to status register */8 L% D( z1 H8 ^# b; t6 b4 N
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    / b6 s" d3 a% K! F- r& N0 B
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */6 l! {( J2 U/ z. |2 g4 z/ R% X
  390.         CE_High();                                /* disable the device */; C; }& Q' m# I
  391. }
    # A4 x/ O( y1 z

  392. : ?) C  u% ?8 ~# a, W2 t
  393. /************************************************************************/
    ! _% N$ v" d* Z2 R( Q# Q+ P. A/ y
  394. /* PROCEDURE: WREN                                                                                                                */4 X+ c) x7 b: n
  395. /*                                                                                                                                                */* e. E/ \* u4 g  a
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    7 s9 V1 v& p0 S
  397. /* to Enables Write Status Register.                                                                        */
    ) c3 u2 k; d6 ?( e  z& ^+ F3 ^
  398. /*                                                                                                                                                */
      I  b) {# z' g
  399. /* Input:                                                                                                                                */
    * r! |( ?# G# j0 i& n4 N" e% [! I9 s! G( A
  400. /*                None                                                                                                                        */3 S+ \, Q% m; J0 x- Z
  401. /*                                                                                                                                                */
    ) E8 }2 d" [* `7 V
  402. /* Returns:                                                                                                                                */8 j5 ~) k) A! ~  M1 ~! I" }
  403. /*                Nothing                                                                                                                        */) O+ N% G+ G( C9 s. G' G% T
  404. /************************************************************************/
    + d$ a) I8 g% s
  405. void WREN()
    + r% {, o) c+ x( @- e1 |) s- G# r
  406. {
    / c* a3 M4 T" L3 N  y+ w8 Y
  407.         CE_Low();                                /* enable device */9 \! z$ y. v4 F$ L5 m3 d% @
  408.         Send_Byte(0x06);                /* send WREN command */  `$ }9 c+ A! x6 `0 @9 c# y
  409.         CE_High();                                /* disable device */' [5 x4 ]( A4 m3 ]9 D! }- S1 p# I$ i
  410. }9 _# G9 v- F5 S9 m; T, A" I: c
  411. * w+ d. \* j! L# T- m  @. C
  412. /************************************************************************/) t. u3 B4 S$ j/ p/ T4 h+ R: C5 \
  413. /* PROCEDURE: WRDI                                                                                                                */
    : o( S1 U- D, u- u+ d8 p( H
  414. /*                                                                                                                                                */( N- U. H& d* {# W% f
  415. /* This procedure disables the Write Enable Latch.                                                */+ y6 m- x; X( G) c. d
  416. /*                                                                                                                                                */
    - }1 x6 R$ z( j" |+ y
  417. /* Input:                                                                                                                                */9 M# ]% b4 _) J% Z5 I) V
  418. /*                None                                                                                                                        */% v. B- j) D6 w' M& y" m
  419. /*                                                                                                                                                */3 l/ G9 Q9 |; B$ Y2 O( \
  420. /* Returns:                                                                                                                                */
    * w# r$ ]# T( z, R  @9 w+ A
  421. /*                Nothing                                                                                                                        */
    1 t4 ]" R- m$ W' C- q
  422. /************************************************************************/8 V( O& J* B+ u, \+ @( Z
  423. void WRDI()
    ( W0 V9 H! K. D; C- @* Y6 m
  424. {
    4 |/ X( P* J( z8 [7 ]$ T
  425.         CE_Low();                                /* enable device */4 `  J; f& N+ F' ]1 V2 c2 B
  426.         Send_Byte(0x04);                /* send WRDI command */2 ~- a: c! h) t$ |" l! \8 z" N. c. z
  427.         CE_High();                                /* disable device */" J8 J9 L4 B9 g/ e
  428. }
    2 c, X/ ~- O! @* k/ e1 K
  429. ' L2 w- q. Y" h1 f5 y
  430. /************************************************************************/2 {' [) \& ~( Z( R- N1 c' A
  431. /* PROCEDURE: EBSY                                                                                                                */
    3 O. T' m/ f  N; O
  432. /*                                                                                                                                                */: ?+ R& |" s  M* S* [) Q4 J8 _9 Z1 N9 ?
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */( z$ h8 ]9 A2 ], o4 n
  434. /* programming.                                                                                                                        */0 H, f' `$ _' ?% s3 b9 F
  435. /*                                                                                                                                                */* x- X9 |9 D. f& S4 ?8 }) u
  436. /* Input:                                                                                                                                */) K+ p1 U6 W/ D. S$ H
  437. /*                None                                                                                                                        */
    2 d  g! X; _& u7 g" C
  438. /*                                                                                                                                                */; H; c' _+ b! _- G! J
  439. /* Returns:                                                                                                                                */
    ; R* X' S7 b1 }" ?# A$ m
  440. /*                Nothing                                                                                                                        */3 E3 \9 v3 y. h9 u5 @$ k1 g
  441. /************************************************************************/
    ; V: y7 K2 C+ v+ X  m
  442. void EBSY()& x4 j. K$ ~! P
  443. {
    1 W, [% b5 z: i( z8 C( b. m
  444.         CE_Low();                                /* enable device */1 B! U( ~. T, T& x& n0 r4 ]) T
  445.         Send_Byte(0x70);                /* send EBSY command */
    6 v% v4 X8 B" D5 g7 s
  446.         CE_High();                                /* disable device */* U$ q2 ?& |+ T" t" w
  447. }" G) I# S& A& \* u# |* g

  448. 2 @) g) j) T& g# r3 Z7 O
  449. /************************************************************************/% v* d* V- w: u7 i5 _1 a# ~2 W
  450. /* PROCEDURE: DBSY                                                                                                                */0 x! Z0 r- r( M! ?
  451. /*                                                                                                                                                */
    8 [) M2 j' \- u4 P4 a% t9 N. B5 F4 ]
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */- H) _# c/ f+ U; ^! L3 b6 B0 ~! C
  453. /* programming.                                                                                                                        */
    & W; |0 R& _/ U/ R. L
  454. /*                                                                                                                                                */
    * f2 O6 U0 \6 P2 R
  455. /* Input:                                                                                                                                */3 E( b; r7 p* ~/ F- h$ n- i
  456. /*                None                                                                                                                        */' l0 X& E3 D. W
  457. /*                                                                                                                                                */7 m  P) s( i9 c* r
  458. /* Returns:                                                                                                                                */
    2 a# c9 E' }3 Z4 f6 c, b9 p7 @
  459. /*                Nothing                                                                                                                        */, w3 w+ j) I8 ^" c! Q) B4 {9 X
  460. /************************************************************************/
    . J2 h6 d& t; H/ j& z
  461. void DBSY()
    / i! @# s! \* ?! Z: e6 C
  462. {- T8 n) D. i5 ~* j2 [4 L
  463.         CE_Low();                                /* enable device */
    / b! w4 X$ |  C  I! h( S
  464.         Send_Byte(0x80);                /* send DBSY command */6 _. P$ f9 C. W
  465.         CE_High();                                /* disable device */
    1 ^9 P+ T9 g) j) R, r( c
  466. }
    - [5 P  ?- S3 u% }: X; x
  467. 2 T6 k4 S; t& P* h
  468. /************************************************************************/
    & c2 G' h0 t1 `6 K7 g3 K$ Q
  469. /* PROCEDURE: Read_ID                                                                                                        */
    3 b) v8 s7 a- ~* ~  t9 Q7 T8 I1 k- ^
  470. /*                                                                                                                                                */
    9 M% d& H& g* v+ ^
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */; Y: y, `6 L9 i/ a4 O
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    ' i6 A( Q% f( T) P
  473. /* It is up to the user to give the last byte ID_addr to determine      */4 y5 _: t, ]4 Q
  474. /* whether the device outputs manufacturer's ID first, or device ID         */1 b4 v- v6 g8 v+ X
  475. /* first.  Please see the product datasheet for details.  Returns ID in */% \# e' I$ ?/ N
  476. /* variable byte.                                                                                                                */1 {9 z5 z1 M2 F2 w0 _+ g+ ~
  477. /*                                                                                                                                                */
    % V, h* J9 G# K/ S
  478. /* Input:                                                                                                                                */9 a0 i' D! w2 A& g1 l. |7 V
  479. /*                ID_addr                                                                                                                        */: b% o9 t. Y3 }1 Q# Y# S
  480. /*                                                                                                                                                */
    * z: H9 K, K7 k9 G; t9 n$ {# _/ S
  481. /* Returns:                                                                                                                                */* `9 w9 C. W) t6 t
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    1 I! f& a7 x$ [7 b0 C" V) x" ^
  483. /*                                                                                                                                                */
    ) o4 z. H& m* `( L) b% ]3 S
  484. /************************************************************************/
    9 h8 Z$ b0 n, g, x; O$ s; F3 p
  485. unsigned char Read_ID(ID_addr)- l, W% E9 k: ]- y2 l, E
  486. {0 p. e3 B: M1 w" d, t7 H- H3 ~
  487.         unsigned char byte;
    0 N* U. N7 r; @" J: H
  488.         CE_Low();                                /* enable device */3 v. t( `" f+ Y. S& A- k
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */$ k2 ~8 r7 H- h- m" e5 m
  490.     Send_Byte(0x00);                /* send address */
    6 v, Q- I0 t. U0 Q# X
  491.         Send_Byte(0x00);                /* send address */
    7 @4 U4 B1 |6 A, V7 G& z
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    " J* h/ b, L8 f8 {) c: s2 ^- e
  493.         byte = Get_Byte();                /* receive byte */. m% j- c" U( H& F* ]" `
  494.         CE_High();                                /* disable device */
      R0 ^; N3 R+ ?" C( ?
  495.         return byte;
    + A' T% n& \1 i/ ~' r& T1 v4 o
  496. }
    / U* j6 \% i/ Z  V* L2 d

  497. . G( V$ ?" D4 B" {
  498. /************************************************************************/8 m0 X8 A* H9 R. R0 u# N
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    " ^& ?) [# N3 J: [
  500. /*                                                                                                                                                */
    * t1 w2 Y5 j0 \3 V7 I% F* B6 y
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */$ L$ t# a9 U' B& d
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */# y3 _9 j9 F' C& N* t
  503. /* Please see the product datasheet for details.                                                  */. x, S; n2 ?0 X8 }
  504. /*                                                                                                                                                */; ~# T/ C- j& k2 S$ W
  505. /* Input:                                                                                                                                */& o0 ^2 F) t% g- Z% M+ o
  506. /*                None                                                                                                                        */
    ( e" V( r0 E+ H  x* E
  507. /*                                                                                                                                                */
    4 ^* b- Y+ N( C+ ~" b; Y' G! w1 U
  508. /* Returns:                                                                                                                                */
    ) {6 W7 i7 }6 H
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    % l6 Z4 B- a4 A5 u) q
  510. /*                 and Device ID (8Eh)                                                                                        */7 @+ v! d% I% \, P) l
  511. /*                                                                                                                                                */  v: a: a( l# W
  512. /************************************************************************/
      D: O. i) K' N) m: @# g- y: ?
  513. unsigned long Jedec_ID_Read() * Y' ^8 `- O2 N8 M
  514. {
    , n3 r  G' y, A- z5 x; b6 Z
  515.         unsigned long temp;
      I. \* Z4 n$ i* K+ D  e: h" ~4 F
  516.         1 D9 B2 Q/ X; D) l1 n
  517.         temp = 0;
    # Z4 ~! ?) R. {' K

  518. * o7 i4 W" F- p$ r
  519.         CE_Low();                                        /* enable device */
    ( a- v5 D$ [; u* v% O: a0 E
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */  G2 Y* o+ G- n$ C0 l& Z5 e+ F
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */( p+ ^4 L  o; G( E' L2 n
  522.         temp = (temp | Get_Byte()) << 8;        % K7 |! d7 U6 A, L
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */$ K" t& w( f+ w' j7 f3 ~
  524.         CE_High();                                                        /* disable device */- |' X# e# u3 j! g6 v% Q
  525. & }# [( b4 ]0 z; K" _' S3 C
  526.         return temp;  q: n' D& A- ]6 W9 `
  527. }
    1 E6 O7 [+ z" ?0 Y+ e

  528. ! j: ^% n* Z& N' X: h1 j( C% i
  529. /************************************************************************/. }: o  v- N3 Q4 l
  530. /* PROCEDURE:        Read                                                                                                        */
    3 c! _8 s/ _3 B2 ^9 A
  531. /*                                                                                                                                                */               
    * N% @  I( m' t3 u& n( n) c$ j
  532. /* This procedure reads one address of the device.  It will return the         */1 P1 W5 J% N! c/ o, k0 W6 d
  533. /* byte read in variable byte.                                                                                        */
    8 \* q" h7 z) |% I6 X
  534. /*                                                                                                                                                */
      ]  L+ ]  ~+ Q% k8 a  m0 G
  535. /*                                                                                                                                                */
    # ~* H8 G  w$ ^! B8 V" `. N# J: L6 M
  536. /*                                                                                                                                                */0 \3 Q* B5 y0 V1 E( x3 S
  537. /* Input:                                                                                                                                */% M3 m& T  e  i
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */% J6 I- m( T5 |; U
  539. /*                                                                                                                                      */  S- [& z* L7 i% a8 W: t
  540. /*                                                                                                                                                */8 z9 O6 x& A( |% b( w. x  D  n
  541. /* Returns:                                                                                                                                */6 P. E8 T1 n0 |: C* ~* O
  542. /*                byte                                                                                                                        */
    0 V0 Y% o( M2 e7 e2 K8 p8 P
  543. /*                                                                                                                                                */
    0 x# t, |7 d6 v' i
  544. /************************************************************************/
    7 Z6 A# W4 Y: V$ h! Z
  545. unsigned char Read(unsigned long Dst) : O& P/ I8 b5 W
  546. {( j! C. ^' d5 \7 w& e9 {/ d; J& z4 M
  547.         unsigned char byte = 0;       
    " H6 |0 k6 v( O7 _2 U6 M$ j' ^

  548. ' u. Z3 X7 O) [) v* V
  549.         CE_Low();                                /* enable device */2 d$ d. I( R; B; U$ i
  550.         Send_Byte(0x03);                 /* read command */
    / m* R  S1 T& B
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ; Q7 S  z! a6 x5 I
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - R$ s' y# Z$ |" D# J
  553.         Send_Byte(Dst & 0xFF);
    ! w& x, P) c  F& q
  554.         byte = Get_Byte();: j8 ~+ b% M& b0 Y& Q; h
  555.         CE_High();                                /* disable device */
    - f2 \: {# Y  t
  556.         return byte;                        /* return one byte read */
    / C$ b0 {% j% q
  557. }
    0 L- F2 M; l' f' A  P5 h
  558. 3 P0 x3 s* b# x4 F$ N4 s
  559. /************************************************************************/" }% b5 |, D4 Q; V8 L
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    ! @$ t8 Y! J/ Z0 }+ B0 D) ?
  561. /*                                                                                                                                                */                4 ~8 c1 Z' g1 h: _1 G) j
  562. /* This procedure reads multiple addresses of the device and stores                */
    " Y+ C9 ]: ^( o( P! ~
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/- M" `  }" F% }/ D
  564. /*                                                                                                                                                */! }9 C* z; J; `6 ^. Y4 }) Q
  565. /* Input:                                                                                                                                */6 X) i1 b& m  U8 w6 ?: J
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    - K, L8 }5 [" Q& Z: f; L% y% G' {
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */3 E0 S8 r& F4 I: w1 M
  568. /*                                                                                                                                                */
    6 I/ n, K1 ^/ E  H
  569. /* Returns:                                                                                                                                */
    . M+ q0 W# x6 h: K9 w5 j
  570. /*                Nothing                                                                                                                        */
    7 U& U8 O: c5 x* ]- D- E6 \
  571. /*                                                                                                                                                */- x% g( \  C- m! D! z
  572. /************************************************************************/
    5 n2 _8 j( Q4 g2 j( G: _; t
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    % v3 I0 ]4 |' t3 A
  574. {7 D1 j, `) \4 ~, Z/ h
  575.         unsigned long i = 0;" ^* p4 M4 [( a! N
  576.         CE_Low();                                        /* enable device */" x- e: ^* b. G' I6 p
  577.         Send_Byte(0x03);                         /* read command */
    + I. S* O1 z  X2 G4 T' L5 n
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ' p& p4 c2 N2 X2 Y6 B; I
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ( C% a  M% y$ j+ v
  580.         Send_Byte(Dst & 0xFF);" I- {  E( Q3 H( o# T9 s  V
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */9 \8 G% r3 B" T$ G' U# {
  582.         {8 q, P0 W$ C+ a7 n4 C
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */+ b- ?0 e' b; T6 k7 D8 y& b. z7 v
  584.         }
    8 b( @$ y' z/ q9 o
  585.         CE_High();                                        /* disable device */; q1 T9 z9 S9 h! t( `% w. \. p- `
  586. & F" ]% D+ E& M8 Y: U- s
  587. }
    $ D2 H" j2 K, U+ C# I. @) c

  588. 0 w* j1 M& [2 |$ i1 X- i4 z
  589. /************************************************************************/
    , i. c. H$ @% h5 k9 u& h# s4 j
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */, Q* H' h8 i5 b; j+ m+ z1 m& Q: U
  591. /*                                                                                                                                                */                7 @! b' }, j( B. k3 r
  592. /* This procedure reads one address of the device.  It will return the         */
    ; e  y7 T( W- y' w
  593. /* byte read in variable byte.                                                                                        */1 p# Q/ J7 f  u' @0 g
  594. /*                                                                                                                                                */
    / |, A! j" W! W: Y$ A( \; M* W
  595. /*                                                                                                                                                */
    0 Q! Y2 V2 M3 U/ l
  596. /*                                                                                                                                                */& I% Z( [/ Z4 ?) a
  597. /* Input:                                                                                                                                */
    , s& v8 n- o8 v
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */: _1 ^# G% d* R7 l7 {$ }9 w
  599. /*                                                                                                                                      */
    / C7 Q( Y" X* k
  600. /*                                                                                                                                                */
    7 J  N' d+ @% t
  601. /* Returns:                                                                                                                                *// p! M' q6 w: y
  602. /*                byte                                                                                                                        */, Q) R$ T0 @! d3 r" K
  603. /*                                                                                                                                                */4 I+ m4 ~5 @9 o% ?$ u
  604. /************************************************************************/2 a5 a+ Q/ ^; ]- u
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    5 o& I+ [/ C$ a- Y; O7 e$ n
  606. {5 Z- b) E- }4 R) q' _
  607.         unsigned char byte = 0;        , e  a/ D. T; w  m+ j9 ^+ r

  608. + U1 H* L8 @; ~; e, i7 |' H
  609.         CE_Low();                                /* enable device */
    $ g$ m9 t0 j, F0 w" m) z0 c
  610.         Send_Byte(0x0B);                 /* read command */& ]7 `! ~# }, B
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */# d& |& B5 y! n( m8 ?- M6 s, @
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));# r3 U5 q7 Y% n4 M' C4 ]
  613.         Send_Byte(Dst & 0xFF);  {$ S  ]* v3 O% P' c
  614.         Send_Byte(0xFF);                /*dummy byte*/
      W; Z) N& o0 K9 H
  615.         byte = Get_Byte();
    2 b6 p- S5 ^$ E$ T5 w) i
  616.         CE_High();                                /* disable device */* H' H7 C4 B: i
  617.         return byte;                        /* return one byte read */
    $ T5 P* B& e) N1 s0 ?  _
  618. }  i, P3 q" g4 F4 p# S

  619. 4 P5 ~! K( K7 B
  620. /************************************************************************/8 R3 R9 M" v1 p# G2 j; h/ R8 z5 R
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */+ Y; I' J0 \: P1 i  @  d! G2 b8 q
  622. /*                                                                                                                                                */                , U4 V, D; b7 T% h; ^
  623. /* This procedure reads multiple addresses of the device and stores                */
    6 d0 b5 b5 O% X
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/& n. V$ X9 I6 t, P' i) J7 A1 C
  625. /*                                                                                                                                                */2 }( L5 M: G- s" t7 z6 T3 ^, ]
  626. /* Input:                                                                                                                                */
    . G0 c. U! p. A7 O# _1 S
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */3 G* o. i' w9 d. @) r4 k
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */7 J. s, M9 Z. L4 |
  629. /*                                                                                                                                                */. j+ l) J- h; g
  630. /* Returns:                                                                                                                                */
    / ?/ M' c! J3 D' @; r( L
  631. /*                Nothing                                                                                                                        */
    - Y$ k) F1 M; r2 X
  632. /*                                                                                                                                                */+ l) ^. z  U3 d, G2 Z) X( F! `
  633. /************************************************************************/
    3 b+ ~- m& x# H7 ?' m
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)/ S9 O0 B! G, g, G8 V  l2 j
  635. {
    : E1 u2 M7 o/ R( j( O
  636.         unsigned long i = 0;
    " n% y0 {7 f4 n9 Y) l
  637.         CE_Low();                                        /* enable device */3 _, h$ a7 q+ m. U& O. d7 o
  638.         Send_Byte(0x0B);                         /* read command */
    7 l; T# ~, p7 `. ^0 u) R
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */; M( P) T! {! @4 N
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));' m, a( Y' k2 L
  641.         Send_Byte(Dst & 0xFF);4 _8 S1 j7 ?! \' [' k  u7 V
  642.         Send_Byte(0xFF);                        /*dummy byte*/% b) M6 u( B5 J, c( b
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */8 Q' W9 X# b. D0 K% Q& ~2 z, c
  644.         {
      G) N6 e/ B+ i  i, f
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    5 K3 s; a9 [1 F1 J* Z4 s# }! W
  646.         }
    ; ~. w/ z+ i# @8 \  R
  647.         CE_High();                                /* disable device */7 P$ _2 m1 e4 J
  648. }
    + z, }* u% a0 j& V

  649. 1 M5 M+ \* }0 |7 V
  650. /************************************************************************/
    7 f" B# _3 ~) K) b% I
  651. /* PROCEDURE:        Byte_Program                                                                                        */& t* |7 I3 @. N7 r0 L! f
  652. /*                                                                                                                                                */* @. r1 i4 v5 K% {
  653. /* This procedure programs one address of the device.                                        */
    7 Y- o  U& e# d+ I( F+ S. n
  654. /* Assumption:  Address being programmed is already erased and is NOT        */2 Q) K- ?/ F$ F: C8 x9 x
  655. /* block protected.                                                                                                                */# I2 q& f/ B* Z- n( G5 I
  656. /*                                                                                                                                                */
    # f! i2 {8 M! v( D4 k& B% ]
  657. /*                                                                                                                                                */
    & I- p0 H' j( _# a% C! L
  658. /*                                                                                                                                                */8 Q5 i: T1 I. x+ u' z5 o/ I' H
  659. /* Input:                                                                                                                                */$ o& T7 c, N( A2 q6 L6 \3 V
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & e$ |8 e6 d, p
  661. /*                byte:                byte to be programmed                                                                *// O! b% `0 [$ z9 z/ f) Z
  662. /*                                                                                                                                      */
    * \7 n. h0 v" Q- f* E+ h+ V
  663. /*                                                                                                                                                */$ U7 _1 u' d2 P7 t
  664. /* Returns:                                                                                                                                */
    2 Y6 y. g6 H+ R2 r2 `
  665. /*                Nothing                                                                                                                        */) i2 I0 g& T5 B
  666. /*                                                                                                                                                */3 f  J+ F; i7 T7 {5 ~" Q
  667. /************************************************************************/
    4 t: r- {' A0 Z
  668. void Byte_Program(unsigned long Dst, unsigned char byte)2 c% R3 L: z" M; @; h
  669. {+ M" e4 a, A& N" E' Q
  670.         CE_Low();                                        /* enable device */
    " j; Z- c: R) g
  671.         Send_Byte(0x02);                         /* send Byte Program command */3 \1 W8 M$ d7 z$ w
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    # y+ `0 t7 ~3 M. B
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));# ]. p! Z8 g8 b) H% E
  674.         Send_Byte(Dst & 0xFF);
    4 y5 v; ]% _9 V5 r+ W) C6 N) H. ]
  675.         Send_Byte(byte);                        /* send byte to be programmed */, U9 j& l3 c$ x, p! ?! z, Y
  676.         CE_High();                                        /* disable device */, R; n* G4 n2 M9 ?, r
  677. }
    3 Z+ n! @5 e! T" N5 x
  678. 1 m  E. m7 Q$ x/ T( H4 ?5 A( b7 _
  679. /************************************************************************/
    9 U6 Y0 a! @9 r9 |7 a. j, u
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */( b/ t; {5 Z; W
  681. /*                                                                                                                                                */; }/ R8 |' u( r3 D' A
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/6 `9 e" m6 m. k) I/ J: `. ?$ M
  683. /* the device:  1st data byte will be programmed into the initial                 */5 m2 p; |: x: w9 A9 ~& J# Y3 k
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */* }5 P( k  O! q- P' d; P& m; O7 S
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    ! v6 R4 P, K0 g- b! r( R, ]
  686. /* is used to to start the AAI process.  It should be followed by                 */$ G( R+ [* C/ z. P5 B
  687. /* Auto_Add_IncB.                                                                                                                */
    8 `4 ]# ^: w# D8 g7 |' k4 L
  688. /* Assumption:  Address being programmed is already erased and is NOT        */5 k. {& G- K1 p
  689. /*                                block protected.                                                                                */0 e, V' S: F' s
  690. /*                                                                                                                                                */
    , j4 B7 ^" m' x  |- }! e
  691. /*                                                                                                                                                */
    ' w2 H( Y. i$ i, K5 a
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    $ H) L' s' o0 i3 \6 k! v% z; z
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    8 D( k% s3 t1 L$ G
  694. /*         unless AAI is programming the last address or last address of                */( L/ H6 ?  r8 ~- ~
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    + V9 ]" }  S) @  j9 U' g
  696. /*                                                                                                                                                */5 _) ]$ n8 b' r/ X- e
  697. /* Input:                                                                                                                                */
    & D8 q7 h" B  w$ m; v& g, ^
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */1 w  w4 N  r! l
  699. /*                byte1:                1st byte to be programmed                                                        */
    2 N- U* T9 ~  i9 ~
  700. /*      byte1:                2nd byte to be programmed                                                        */, c  L; N3 j4 j& v
  701. /*                                                                                                                                                */
    / e4 u" `' [; }( ^# l( Z
  702. /* Returns:                                                                                                                                */
    * y/ {, n: Z8 }, ]4 A% m
  703. /*                Nothing                                                                                                                        */5 g5 _1 z$ }& h
  704. /*                                                                                                                                                */
    7 ]7 X# p; G/ b; O
  705. /************************************************************************/2 v+ l: z8 K) Q
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2): k6 z! d; u5 |5 C% F
  707. {! O' D; ]6 u1 V, f. i% e
  708.         CE_Low();                                        /* enable device */, @7 u& v3 U0 B( k
  709.         Send_Byte(0xAD);                        /* send AAI command */
    8 @4 G9 ]8 W" i7 n
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    & T) h  ?5 @% Y0 Q. n, k/ O
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));3 P; a! y6 |" w0 f
  712.         Send_Byte(Dst & 0xFF);$ }8 N; X; `7 T* z/ Q% U8 c4 ^
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    1 @% S; D9 j7 b: W" v
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    : n* e# D- X9 e- r- w8 d! u: J5 E
  715.         CE_High();                                        /* disable device */6 Z7 Q+ Q; c2 m: X" g
  716. }
    6 w" X+ s. N% s- e; k0 \, U5 }5 H
  717. ' q* d" A: l2 _4 h9 v# `
  718. /************************************************************************/
    $ o* h, {8 _6 H" f; a3 t1 i: X' ]
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    / K: q5 y8 Q. O1 d
  720. /*                                                                                                                                                */0 ]) p! l! R' K
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/, q/ I2 \! C$ y6 t
  722. /* the device:  1st data byte will be programmed into the initial                 */2 ^0 o( h. C; T. D4 `( w
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    2 K1 {6 q: N' ?: g! I
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    + A, M% K0 z! _, e' ?
  725. /* is used after Auto_Address_IncA.                                                                                */  K/ ~# F0 P7 i2 S% X' o+ ~
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    5 D1 \' V1 c- M% H* {9 i
  727. /*                                block protected.                                                                                */
    ' }/ {& w" X2 `
  728. /*                                                                                                                                                */
    2 A% p; M( T$ S3 L) M! S! [
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    5 i% l- G. n# T# q5 e7 J0 B
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    ' @8 O# B: A8 t5 A% U) A4 F3 Q
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */  y1 @+ M  n0 f, B' \6 y5 s2 p6 R
  732. /*          to exit AAI mode unless AAI is programming the last address or                */7 V; a, M; }  j0 I( h/ r8 q
  733. /*         last address of unprotected block, which automatically exits                 */
    # K# F  ?& |: ^# R; G
  734. /*         AAI mode.                                                                                                                        */
    # \' X& L; K3 |* c
  735. /*                                                                                                                                                */; c: o0 F0 u- \/ S0 P4 e, U1 [
  736. /* Input:                                                                                                                                */
    % r" F; ]6 ?, i" i8 d1 V) X
  737. /*                                                                                                                                                */& s, b  D  e! t# h
  738. /*                byte1:                1st byte to be programmed                                                        */
    - \9 X1 \7 G6 O" C) `
  739. /*                byte2:                2nd byte to be programmed                                                        */
    ( B8 x0 @" G& X* ~& z5 g
  740. /*                                                                                                                                      */5 ^) J9 b: T/ O% Y' P
  741. /*                                                                                                                                                */
    ) l+ |, s5 h- I
  742. /* Returns:                                                                                                                                */
    " o& a4 u& S8 M" G; I! x, Q, m
  743. /*                Nothing                                                                                                                        */( V# B( o1 h2 @5 y
  744. /*                                                                                                                                                */
    , p* k& b- R; @0 v5 f
  745. /************************************************************************/5 S( \8 ]) Y" k# m1 t  V/ b
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)0 f; \3 ~/ N! z* p: K# l7 v; ~
  747. {
    # b) s$ ?; x; ]/ A% L1 y
  748.         CE_Low();                                        /* enable device */8 W  R4 C! U: ]& r' c- u6 R0 w/ _
  749.         Send_Byte(0xAD);                        /* send AAI command */$ _4 m7 G, p2 J1 ^  `. L
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */9 J+ m& n% m' Q/ ~/ U" Y
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */# \/ A8 c; W" W! u* v9 o) w$ m
  752.         CE_High();                                        /* disable device */
    ( m4 @9 e4 f- i! H, ~. H# f
  753. }
    ! H' j/ Y! d, F8 C. D5 Z6 e& J& e
  754. ) @! m9 d' p* ?, X; B; S) T
  755. /************************************************************************/$ e2 u9 y/ t8 m% a4 h/ e6 O
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */) Y" ]5 r! J. [" r2 Y5 J
  757. /*                                                                                                                                                */- Q1 I- h( E$ k  ~9 p/ j
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */% e1 \1 ]+ F/ r+ f/ \) Z: w
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */( z0 K; M3 V1 e& o$ S- f! q
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    3 w: U/ q2 g1 x0 P4 f4 ?1 y
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    0 ]* K- w7 M# X2 U: Z9 ~2 g! G* l, E* t
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    ) c6 N3 T" C$ F$ O/ I3 e$ X0 Y
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    . A# p4 U% D: ~4 M+ c% L' |( f
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    + e6 g  S; p  O% a+ |
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    ) t) C: y6 O% v7 H! J  ~7 z5 x
  766. /*                                block protected.                                                                                */$ j* r3 S6 Z1 z3 c
  767. /*                                                                                                                                                */6 n! N5 A* ]; _* g
  768. /*                                                                                                                                                */
    9 H! H. x; Q, g, N( D/ o
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */* z5 @5 ?( |! e8 k6 O
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    . D# I1 [- [0 {+ O; J
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */% O. ]2 j8 j, E; A
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
      j' @2 r5 O$ g
  773. /*         last address of unprotected block, which automatically exits                 */1 ?) E8 \% ]+ Y8 D1 N( J
  774. /*         AAI mode.                                                                                                                        */; |7 M8 ~4 a% t% ~6 V6 M
  775. /*                                                                                                                                                */+ Y* ^' k1 k' J! [1 P2 g- b
  776. /* Input:                                                                                                                                */7 @; q" K, V! I- N+ C
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */6 i5 [5 Q' A0 ?2 o+ B( ?
  778. /*                byte1:                1st byte to be programmed                                                        */, m9 }- G4 Q# e) K
  779. /*      byte1:                2nd byte to be programmed                                                        */
    , k% ^- e+ g/ V1 @# l
  780. /*                                                                                                                                                */
    4 C4 e8 X8 c- J3 R* X1 ~4 f3 V
  781. /* Returns:                                                                                                                                */& O& F, u1 x& f5 j
  782. /*                Nothing                                                                                                                        */
    ( r* m6 d) w  t7 M
  783. /*                                                                                                                                                */* y# ]) @, m+ N- _* o3 C0 U
  784. /************************************************************************/
    + P* K2 Q* u- p- a! {- Z3 O- d
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)# b- p, N% N% U$ s3 G
  786. {
    ; c  T2 t- D: E# h4 M0 `2 o# Z% u
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    , i8 a" G4 d3 z- Q
  788. 3 N5 ]: k; j, Q5 j
  789.         CE_Low();                                        /* enable device */  ^" p1 G/ T+ Q' o
  790.         Send_Byte(0xAD);                        /* send AAI command */( {, e- d- I* Q( [. G+ b2 w
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */& A1 p3 K& G; g+ E. M1 h: R! v
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));4 y, z  u. \  Q4 Y
  793.         Send_Byte(Dst & 0xFF);1 I/ {7 R3 c  z2 k  u5 u7 Q$ o$ z1 j
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        6 q8 y# ^0 l3 ~" y, d
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */! l- U- \6 B# |# S: Z* u
  796.         CE_High();                                        /* disable device */5 v8 O5 D$ I7 \9 k( }/ O9 M
  797.        
    $ @$ I7 @1 b5 W# W* Z$ L
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */% ?9 e4 i. [8 ^8 A. C. z! {& K- c* p
  799. $ N4 `) a- F8 G* w- m+ Y
  800. }
    0 S7 S: J: ~1 V% {4 C6 m

  801. 0 K5 w# `( M* u/ V" E
  802. /************************************************************************/1 p% z! @& [8 F' M5 F
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    ) U! v  y9 ]& `" q$ s3 F  f1 g' ^( o- I
  804. /*                                                                                                                                                */
    : A) W1 {  C: S2 S4 n
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */7 g; }2 X- _' o1 Y7 b. S+ S
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    0 o/ m2 @- h! i" J7 F8 x
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    3 M7 V, B1 {$ @9 |$ b7 K8 T. _% @+ D
  808. /* the device.  The 1st data byte will be programmed into the initial   */' B$ c9 f8 p9 j6 \8 s
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    7 Y1 q2 z" V: @' Y' R) Q
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    + A& Z) t/ {- `3 C! @1 x; ]
  811. /* used after Auto_Address_IncA.                                                                                */
    2 b' i6 g4 m( O& c
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    " h/ `  u% `: G" L2 _- W
  813. /*                                block protected.                                                                                */6 X% ?4 G+ T$ W; u5 U' P9 s
  814. /*                                                                                                                                                */
    4 Z2 X  j" O( n9 n4 F
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ; K, z1 N8 A2 |$ X
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */9 T! s% x. n- ]! z* Z- z* B% x
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */" L8 e5 ~) |/ D. H! S
  818. /*          to exit AAI mode unless AAI is programming the last address or                */' Q! P& |; L2 K- P( x: b) d
  819. /*         last address of unprotected block, which automatically exits                 */- e9 b4 @6 C; r" Q+ [2 O0 K5 g! ~
  820. /*         AAI mode.                                                                                                                        */6 Q$ z& l/ U" Y6 Y
  821. /*                                                                                                                                                */
    4 j7 F9 T6 {8 v
  822. /* Input:                                                                                                                                */
    3 M2 \- N6 _2 a6 s3 ~' U6 o4 P" S
  823. /*                                                                                                                                                */: Q+ {: F0 U1 ^& I% ]
  824. /*                byte1:                1st byte to be programmed                                                        */
      r0 E9 b5 M" r9 K$ B9 V
  825. /*                byte2:                2nd byte to be programmed                                                        */" |2 s7 i: \! [
  826. /*                                                                                                                                      */
    3 \7 ]6 w9 N- T2 y
  827. /*                                                                                                                                                */" g4 a; U4 {2 ?- T" d
  828. /* Returns:                                                                                                                                */
    6 d$ Y/ o. I& C. G7 f
  829. /*                Nothing                                                                                                                        */0 B" ]1 V) ~# I+ F
  830. /*                                                                                                                                                */
    ! g, i$ g- l# V& u: p% Q
  831. /************************************************************************/
    ; }  y. T8 y# d* E' c9 E' F3 z9 B
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    ( H1 m- k( R9 }4 q
  833. {& q& r; z  w' B  r% V
  834.         CE_Low();                                /* enable device */. J0 w9 a- V  _4 ]" A* |
  835.         Send_Byte(0xAD);                /* send AAI command */
    7 c% _) i* N  c! Q, h( x$ V
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    / S  R5 X/ b; f# w4 s, B
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */# g8 w- n7 `2 v! G! }7 l
  838.         CE_High();                                /* disable device */+ c# A5 s. Z, {& f5 U. m

  839. 3 i$ H3 P! j/ `
  840.         Poll_SO();                                /* polls RY/BY# using SO line */, D1 d6 p; [9 T% S

  841. 7 g( j; l+ V* C5 }1 |! e1 A
  842.         WRDI();                                 /* Exit AAI before executing DBSY */3 I) U! S& c3 e
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */$ X5 F9 v# f* n" |5 H
  844. }
    " [6 V! a1 h. d# b! F6 _( j
  845. 6 R1 C4 _$ j6 Z# f; R: A
  846. /************************************************************************/) D, Q1 U8 g& Q6 }% f4 `$ ^
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    ( l- A" Q* |9 Y1 W* W& n
  848. /*                                                                                                                                                */
      V% T2 s3 U. \9 F( C
  849. /* This procedure erases the entire Chip.                                                                */
    8 a, g  G% j/ z+ V4 G5 l: \
  850. /*                                                                                                                                                */7 z& c; D* r& O- S3 ]8 u
  851. /* Input:                                                                                                                                */& y; e$ a1 d6 T2 l5 |
  852. /*                None                                                                                                                        */
    3 f* X' l9 P, f8 K! L2 F
  853. /*                                                                                                                                                */' [) b2 ^. ?8 N/ s, Z/ D0 ~$ X! F
  854. /* Returns:                                                                                                                                */5 p! }! i$ _( u  x
  855. /*                Nothing                                                                                                                        */. W; u# y1 t: @: H- D! z! }# Z
  856. /************************************************************************/
    0 L, \1 p, H% x/ c/ e/ o
  857. void Chip_Erase(). |7 z# o4 j. o; Q1 @" ]! M
  858. {                                                1 X9 h$ z& S+ O, M+ U9 m2 D2 w  t
  859.         CE_Low();                                /* enable device */0 Y. t. i& W" g9 S$ \& z1 ^
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */( \3 v8 u6 M( f" v+ V# o! N
  861.         CE_High();                                /* disable device */2 I( a' a8 P5 N! z5 f) w/ D
  862. }
    7 K/ @3 [9 q7 e

  863. * X/ u( E% z7 U; e) c4 {$ \
  864. /************************************************************************/8 D% b' M( |" z! }/ y7 `
  865. /* PROCEDURE: Sector_Erase                                                                                                */& X5 Q8 s; l- x; n
  866. /*                                                                                                                                                */
      G9 S3 p0 p$ x+ V( r
  867. /* This procedure Sector Erases the Chip.                                                                */' p) b7 _  g( n2 Z
  868. /*                                                                                                                                                */
    9 f/ u9 z2 S, ^! @; o
  869. /* Input:                                                                                                                                */
    ' g: W# I5 C9 I' q  H- K
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & \" p8 @. X: x
  871. /*                                                                                                                                                */; d0 r7 c4 c& p. S) }0 [* b
  872. /* Returns:                                                                                                                                */
    0 L2 h, ]& v  Y. z* T
  873. /*                Nothing                                                                                                                        *// g! w+ `! ]& J+ ?; l3 _7 W
  874. /************************************************************************/
    6 E) ~' N1 F4 }0 B7 Z4 ~9 n' R
  875. void Sector_Erase(unsigned long Dst)
    / \- \0 o, L0 f5 _
  876. {) s0 ?7 e# a, a8 ~( s/ l9 o
  877. : m4 c$ X0 V/ ]6 z

  878. , \  H% [4 q% X) w% g4 n, [% t
  879.         CE_Low();                                        /* enable device */
      G& ]& ?& ~$ d8 l
  880.         Send_Byte(0x20);                        /* send Sector Erase command */0 q7 y- G' M8 Y1 S% N1 Y/ U
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    # `/ t' R) x3 Q- T3 ~
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));+ `6 k2 E2 j# ]5 p& H7 R
  883.         Send_Byte(Dst & 0xFF);# h+ Z5 u! V8 |0 U  P: n+ ^6 N8 `4 g4 Q
  884.         CE_High();                                        /* disable device */6 o5 C% u9 q( V7 S
  885. }        : Y% ^( E  \! P. `
  886. 8 B9 T. E$ e/ _' b4 ]- [
  887. /************************************************************************/
    3 H( M5 c( l2 G/ f* [
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */2 S: r9 T3 ]$ s6 k9 M5 s7 ]' G1 K  m
  889. /*                                                                                                                                                */, m# O* a: ~4 b0 M' v9 x& X4 c
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */( f' }% j( i( O% ?: _
  891. /*                                                                                                                                                */
    ; O0 N4 ?* K1 O$ O
  892. /* Input:                                                                                                                                */7 W" \$ ^3 c, m: Q* h) z, z+ ~" C/ |
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */8 n' L" y/ b+ f5 x" h* \, O& y
  894. /*                                                                                                                                                */
    ! Y+ e4 R4 _2 {$ q
  895. /* Returns:                                                                                                                                */
    / M& Z7 _, T$ R% N8 U
  896. /*                Nothing                                                                                                                        */
    $ D- O" B$ p2 r3 X* q; L
  897. /************************************************************************// S& r9 T  C2 _$ M2 Q4 H! N7 S8 {
  898. void Block_Erase_32K(unsigned long Dst)
    ) i1 t2 Z0 X# x! a' `2 u+ q
  899. {- F; p1 |/ j, f
  900.         CE_Low();                                        /* enable device */
    7 D" P" q$ S  d% O1 T5 ?# y
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */3 @) |1 Y/ u2 U, M- z
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */+ c- J6 O' d) c0 d
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));, x, j% {. I, L% w$ Y7 c1 o- K0 @. x
  904.         Send_Byte(Dst & 0xFF);+ o( W' R4 O/ K2 t+ }3 X5 ]
  905.         CE_High();                                        /* disable device */) `: R+ N* Z+ _+ I  {! \: n% S+ h
  906. }
    : w) K; `8 B# T  T

  907. 8 d$ N! K! `6 c
  908. /************************************************************************/6 A0 k$ T- q+ Y5 t& x  y
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    : @1 z7 v1 j/ S
  910. /*                                                                                                                                                */* S9 |+ D1 }% u+ J# t  @* J
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */& u2 d; _8 K( A' F$ t# L% D1 [
  912. /*                                                                                                                                                */
    2 B( C6 O9 ]. @# |) e! N
  913. /* Input:                                                                                                                                */
    5 ^( R! ~" C+ o$ W/ B$ C
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    5 W& m# U7 e0 [
  915. /*                                                                                                                                                */
    5 z6 T0 X7 H5 j  u" X/ C
  916. /* Returns:                                                                                                                                */" b% G$ E+ S1 |8 }: L! k7 ~% H4 I2 q
  917. /*                Nothing                                                                                                                        */- k6 q! w+ H: Q( e0 c
  918. /************************************************************************/7 [+ O* E! c" [6 Y& ]
  919. void Block_Erase_64K(unsigned long Dst)5 n- U  `; x3 G( G5 g5 y9 {
  920. {+ J3 B# B& C" k0 `
  921.         CE_Low();                                        /* enable device */  n4 o( N3 {/ O  }
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */1 s: F. w3 z2 x8 B+ j
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */5 Y( e" [- _, b% k% o6 L) q9 v
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));, Y# Q) e6 X5 o, `3 `( U7 p9 r
  925.         Send_Byte(Dst & 0xFF);$ _' ^/ p  @1 ^: r/ p$ n' v
  926.         CE_High();                                        /* disable device */
    & ?$ B* \. B$ m4 V' t" ^8 w
  927. }
    4 B9 `2 B, [# Y" J/ d$ B) l* g) U
  928. ) k8 j8 w/ U6 f7 M0 H0 k
  929. /************************************************************************/; a$ l7 I! W; z; ?# f( k" g0 ^2 |
  930. /* PROCEDURE: Wait_Busy                                                                                                        */1 a( n( J- X+ c9 a
  931. /*                                                                                                                                                */
    & S1 Y. @7 h9 a% ^! I
  932. /* This procedure waits until device is no longer busy (can be used by        */6 P3 A* M7 I- M! L8 H3 ]
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */; L, R; _- ?1 @! A8 i4 {+ ^# S
  934. /*                                                                                                                                                */2 Q, j& X( }: W6 g5 [
  935. /* Input:                                                                                                                                */
    7 u5 c) X0 m( E( Z: B
  936. /*                None                                                                                                                        */
    4 v$ |' M, i7 d: \6 I
  937. /*                                                                                                                                                */- i* V* @3 @/ P* a* p
  938. /* Returns:                                                                                                                                */. a# g6 y& `. C- Z$ \. L8 r% z
  939. /*                Nothing                                                                                                                        */) N! ]- G5 F+ ?/ n, s; T# Z
  940. /************************************************************************/: t+ S0 D' Q- B# i4 a+ z- d* p
  941. void Wait_Busy()7 o2 x4 I/ q3 ~  J
  942. {: y) d9 p  d8 |+ R3 ~
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    3 Y8 X! m' ?: O0 Y4 Z4 l- p
  944.                 Read_Status_Register();
    * V9 y+ |9 V2 E
  945. }9 W8 C) @9 s; v# h. @$ ]- V- A

  946. 2 G( f. \3 E; d& ?
  947. /************************************************************************/$ R9 x# ?$ m: w
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */8 c/ x/ m6 N7 H3 w9 f
  949. /*                                                                                                                                                */
    $ Z) N2 Z6 }$ M! b6 k/ j7 W
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    ! G7 j; {6 J5 x3 z5 d# m/ C2 G8 d
  951. /*                                                                                                                                                */: _% _" u6 j& U# ~
  952. /* Input:                                                                                                                                */3 R6 r5 ?( G# z
  953. /*                None                                                                                                                        */
    3 ~% l" A! t7 q! G
  954. /*                                                                                                                                                */
    * D' [! D( \; J9 u; ^6 N
  955. /* Returns:                                                                                                                                */
    9 C( j% O9 ^* Q5 i" i& C, R
  956. /*                Nothing                                                                                                                        */
    ; _, N# f  @" W. ~
  957. /************************************************************************/+ P" ?; D1 n0 E, f- g9 B5 n9 q2 f
  958. void Wait_Busy_AAI()7 z- e5 F/ t% y0 z' x  G2 I  ]# x
  959. {
    - }9 p; e9 u4 v3 j
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */0 e4 o# G/ d2 S& T- S  l
  961.                 Read_Status_Register();4 T) z7 Z) F* K1 x
  962. }
    $ K* g3 z" u: x' k( t

  963. % z* {) I, K' Z4 [* ?& n
  964. /************************************************************************/+ B( u  G# E; o9 o: O) q
  965. /* PROCEDURE: WREN_Check                                                                                                */, H0 d7 ?1 M% U  [
  966. /*                                                                                                                                                *// {* e) \4 C0 S$ ^, r  S' j0 _9 ^. A
  967. /* This procedure checks to see if WEL bit set before program/erase.        */& e% j: ^7 e9 Y$ R) |  N' w
  968. /*                                                                                                                                                */
    0 w. R9 ?, D' S' I# h
  969. /* Input:                                                                                                                                */
    * c( w0 Z, H( T5 R+ I6 x6 Y3 T
  970. /*                None                                                                                                                        */
    $ Z* V1 o! Y: R  y
  971. /*                                                                                                                                                */% O  J. `* M3 U  M. r) v
  972. /* Returns:                                                                                                                                */
    - }7 x8 r; e% s( A5 [% V8 T! o
  973. /*                Nothing                                                                                                                        */% H4 x9 U# w7 S" J7 a8 I, W& Q* m
  974. /************************************************************************/
    $ l9 s1 m+ U! t! [5 ^, Y
  975. void WREN_Check()) T% v3 g  O- i" ^% _2 w& B
  976. {
    6 T( t* q6 x2 x; U
  977.         unsigned char byte;
    . h  ?' e" c3 L, D) |; j
  978.         byte = Read_Status_Register();        /* read the status register */
    1 S4 a; w9 @; ]( b- c/ B
  979.         if (byte != 0x02)                /* verify that WEL bit is set */, v3 z8 q" y3 [
  980.         {
    1 {" ~& _: h) Q* E) L' q1 x
  981.                 while(1)% W: i( E+ F0 d0 Q4 j* A" t, v! {
  982.                         /* add source code or statements for this file */
    : V4 S% C, X5 t& P. g1 m- W' ?  m# F
  983.                         /* to compile                                  */) y$ {7 M+ q3 D8 P9 V! X0 y5 r
  984.                         /* i.e. option: insert a display to view error on LED? */
    % D# @3 o4 {7 J6 A! O
  985.                  0 Z; w: u/ v( n% v" Y
  986.         }" Y9 @  h1 O# V0 F8 ~+ s; W7 o
  987. }
    / t- W: T5 ]9 N2 j

  988. * z0 X) y$ \: l6 `
  989. /************************************************************************/
    : u" y# Y$ k) `1 Q: S& l) V
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */. y' ~. l3 X  i' l
  991. /*                                                                                                                                                *// L( }7 Z- _% H8 J5 S
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    , r% X  K9 C2 X/ }7 \
  993. /*                                                                                                                                                */- c- t  u0 z- t: y: O& G1 v' J3 t
  994. /* Input:                                                                                                                                */
    " q: ?( Q2 [0 e: m6 z
  995. /*                None                                                                                                                        */' U% i* Z! I0 f% F7 {5 {
  996. /*                                                                                                                                                */  H1 `' n1 c9 _! Q3 O3 c
  997. /* Returns:                                                                                                                                */) @; P' _4 K, g7 z* u4 u
  998. /*                Nothing                                                                                                                        */
    - M6 N# g/ A7 r" M  G- N
  999. /************************************************************************/
    ' |  O# Q( i4 J1 G1 ^) j
  1000. void WREN_AAI_Check()
    0 F! u; M4 |8 o; h: }5 Q6 @! W/ ]
  1001. {1 ]' x' v6 e' c9 H$ j( `5 i
  1002.         unsigned char byte;
    - n# a9 G, y" b9 G. A
  1003.         byte = Read_Status_Register();        /* read the status register */: F, J! ^4 I/ X" o  ]
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */6 @5 |$ a* Y) W! A
  1005.         {
    % q& D) R9 H1 M% ~$ a
  1006.                 while(1)               
    0 D4 {6 d& H+ v: h8 J4 X- A
  1007.                         /* add source code or statements for this file */
    / X9 x! ~# s/ u0 G1 Z
  1008.                         /* to compile                                  */6 R; t+ d; S, W5 y- T
  1009.                         /* i.e. option: insert a display to view error on LED? */4 d) f) e8 M8 U  c. f

  1010. * d' K6 O2 A" v8 a
  1011.         }
    - y3 v3 [" X4 i4 v/ P6 H
  1012. }( _! N# }! R! l1 c3 U3 z; l

  1013. + b# z# `$ I- q! g1 g
  1014. /************************************************************************/
    ' u; L/ w) ^  c5 G5 H
  1015. /* PROCEDURE: Verify                                                                                                        */' U' `, U/ N& y$ P, |
  1016. /*                                                                                                                                                */
    ! y. m; {8 ?( B8 e; P4 W: k
  1017. /* This procedure checks to see if the correct byte has be read.                */
    - n/ A  |( v' k
  1018. /*                                                                                                                                                */3 r& }; c! B' |0 h, c: ?
  1019. /* Input:                                                                                                                                */
    . x, [* e+ a' e
  1020. /*                byte:                byte read                                                                                        */0 t) K" P+ y5 d, ?
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    " O. r; G' Z% |3 z
  1022. /*                                                                                                                                                */2 O, g5 d$ O) W, q% {; W
  1023. /* Returns:                                                                                                                                */
    2 O, F8 l# d! p7 G) c6 ]! E1 O- y
  1024. /*                Nothing                                                                                                                        */" Q$ i/ @# i2 y; |( W0 W: z
  1025. /************************************************************************/1 g8 K; @8 H& B7 K( i
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
      G- H0 c4 t- T, F4 y
  1027. {
    . O$ `( k5 ]6 T$ V( \
  1028.         if (byte != cor_byte)3 f- _2 \9 F& x4 [
  1029.         {
    " O1 y8 ?4 {/ a4 j3 _: p: @7 q# V
  1030.                 while(1)  ~+ K% S# G  `4 _! K2 ?5 ~0 E, q( {! }
  1031.                         /* add source code or statement for this file */. W1 F# Z0 s+ q3 O* G
  1032.                         /* to compile                                  */
    ; U* `7 \+ G& M: m6 W
  1033.                         /* i.e. option: insert a display to view error on LED? */$ [" b: I! @: k7 L6 |- p  r5 }
  1034.                
    : e$ w. W( I' N" [. T6 Q5 G" x" Y+ @
  1035.         }& f! [0 F/ @2 ?5 f. _
  1036. }( C# d0 W4 J( \) J6 ^% i  G* [/ j
  1037. 7 Y! A6 \% N( g0 @2 G" d; X

  1038. # D; [7 k+ c0 V: i! A6 N' v! f7 j7 j
  1039. int main()* R) }3 A: o# y+ E/ ?4 `
  1040. {
    & ]4 e; b! v& \$ f
  1041. 6 o- S/ Z7 P' q' A* {+ T
  1042. return 0;. C/ I* T; z) |2 o2 ]
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
2 @# l! K  N$ ~) `) O3 Z   main()/ t  v' K+ A! m8 w. u' F: [
   里面怎么是空的呢?7 s. T( P1 A2 x* }1 g' u
   发一份给我吧
8 h8 s$ x9 L2 Amail:luyijun2005@hotmail.com& S  W" M: A& Z* I" ?: j" X
咯。。。。
回复

使用道具 举报

 楼主| 发表于 2007-12-11 19:37:35 | 显示全部楼层
本部分就是如此,它提供的是方法,并不是给你拿来编译的.你要main函数能用来干什么? 为什么不看看 Byte_Program...等函数?
回复

使用道具 举报

发表于 2008-1-8 17:42:00 | 显示全部楼层
如获至宝!请问哪里能找到SPI的官方spec(我不是指flash的datasheet)?网上只能找到些片断...管理员是否可以上传spi spec至本站?
回复

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。
+ g3 }& V  Z9 g
$ C' b2 B; m, o+ t8 H: ][ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
0 |) Y* ^$ N5 S% z. j6 `EC的代码在哪跑,你看DS的说明,每个EC都不同的。
  s6 }; G5 P/ {OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?5 T; y* l# `- D; z7 ^
上面几个问题是你没看任何东西而白问。' A; Y4 n3 n0 Z7 R- C  m/ C3 u
/ Q! R9 Y& D4 T/ q4 I
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
+ M) X6 z1 b6 a4 i
$ l1 a' k$ w7 u关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!; c8 z- u) S  N5 ^7 b

$ G9 P8 J/ e  t, X2 E关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”5 y* M3 s+ }) m5 j5 `& k

+ k5 h# u7 m! E. \+ ~  ^6 p# }关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...0 Z) b: x  N* c* s, [' x' }

& P/ o+ b- a- q  N不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
8 @$ \4 J% M% s1 g+ r) \+ y似乎要把SPI能support 到最大,这EC chip应该有好卖点
, q6 N& k* [6 d9 OBIOS功能要不要强大,也就决定了SPI Flach的大小: M) s( T' T, Y# f
我是这么想的~让OEM去决定要挂多大!* g) D' o- Q- ?
如果我司有BIOS工程师就好了~哈
0 y- W1 F, I( _6 t3 p" mWPCE775应该算很新的东西,来看它支持到多大?
& e4 g5 U0 V5 z, ]' {4 g. Y6 a  F
2 M' G; [/ I7 E, W9 o# {另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte4 z/ X9 l2 K) i, ?% Y3 G- @
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.6 y/ Z1 w% m* T7 ]" x: [1 B$ v, o
+ y2 F& |- q/ W5 i. Y) Z
这份driver收下~希望以后有用到& s9 F" P- Z  x2 `% E. _9 w5 @7 Y
谢谢bini大大
  G8 \$ k6 x- y) c7 n, V2 _( N# p5 C+ e, e1 }. _: s' ~; i
很新很新的新手,如有错误请指正 (准备看第二家的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(): t! \7 ^8 ?5 V8 L
{1 s5 Z( k" f: W" d# O" Y7 M: l
        unsigned char temp = 0;8 p5 x' }# l. f( n# Y, \1 ]) V5 A
        CE_Low();" L/ s- u" F* ~" T" Y6 q8 y
    while (temp == 0x00)        /* waste time until not busy */: p' f) K8 D$ E! j, Y
                temp = SO;
( {5 j0 g) Z8 l# Q* S        CE_High();8 l/ a+ W. L; O' a3 A
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)6 ~( X% v% F, x* v/ b! d& |
{3 j9 j/ O" y3 {) A+ c
        , }, ~* [, Z4 Y+ Z
        unsigned char i = 0;
  o; w6 ]) f2 N+ o* A$ f        for (i = 0; i < 8; i++)
" y5 I: N" Q5 X8 u! _        {
; O- r9 @: N3 c. G1 V& l7 F5 h5 [8 A                6 T' E, @9 I" S
                if ((out & 0x80) == 0x80)        /* check if MSB is high */
9 Q% M! B) b$ K8 L                        SI = 1;/ Z1 h  @- U" c/ M0 K3 c
                else
1 D" K" I, `* f1 o7 n1 r* u. r                        SI = 0;                                /* if not, set to low */
& S5 I: T: s' K9 ^ 问              SCK = 1;                                /* toggle clock high */" e/ X0 I2 l' i! D
   题            out = (out << 1);                /* shift 1 place for next bit */
6 d6 e; w8 X1 B                SCK = 0;                                /* toggle clock low */. F2 F$ J5 a, s' F& ?$ F
        }# \6 O6 h' H% S! s1 c* Z
}) i8 L- }) _" t+ c+ R5 Q, T
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-28 17:55 , Processed in 0.152044 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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