找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 52399|回复: 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
    4 M' f3 b+ x6 |0 G/ u  k2 J3 Z/ a
  2. 3 Z; z2 ]# |' ~. A, X- @5 a
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    ( U% c5 v; m# y3 l

  4. 0 W! T/ L5 M8 w1 h2 I/ y- w
  5. November 4th, 2005, Rev. 1.0
    7 I( d' s5 _7 e& \- S

  6. ' p- A" }8 G, d+ H
  7. ABOUT THE SOFTWARE8 d4 q1 ^( r! z' g
  8. This application note provides software driver examples for SST25VF080B,
    # E( q" Y* d% Z4 _; ]0 _- C
  9. Serial Flash. Extensive comments are included in each routine to describe ' h3 P0 H3 @+ l: f9 A+ C8 }& Y
  10. the function of each routine.  The interface coding uses polling method
    2 p7 d) d" z1 Q' K! L, Q, F$ L
  11. rather than the SPI protocol to interface with these serial devices.  The
    / q7 k) H; w. c1 G7 h5 J% L
  12. functions are differentiated below in terms of the communication protocols8 y& u# S) ?% @% C
  13. (uses Mode 0) and specific device operation instructions. This code has been
    ) d3 O/ e  f# S( a9 D
  14. designed to compile using the Keil compiler.( X2 W3 b1 z6 C/ O: J

  15. + Q( \+ q# u- V/ C9 Z" R
  16. 3 b9 m. M2 s5 {4 I/ O/ j& T5 _
  17. ABOUT THE SST25VF080B
    $ b1 y# X! f7 r9 W' f# A

  18. 8 k, [' e+ h4 s" F* @1 d
  19. Companion product datasheets for the SST25VF080B should be reviewed in " w, y. b* M/ P( y  S0 _% P0 n( V
  20. conjunction with this application note for a complete understanding ) x( Y' ?1 S) `  ?9 z, Z
  21. of the device.
    . E# P( B9 ?# g

  22. * j1 |6 T# P! |' ?; h$ t

  23.   R! }  n8 j  S$ z) m8 a0 w" X+ g
  24. Device Communication Protocol(pinout related) functions:
    2 S8 J" B" ?! t6 q6 f" u9 a  H

  25. % V8 p. {/ s3 }
  26. Functions                                    Function
    8 q7 P9 }# [( f% g! K
  27. ------------------------------------------------------------------4 L  B. M) _# o7 i5 a$ N
  28. init                                        Initializes clock to set up mode 0.
    , u- M" J+ ~1 a. l. x6 k
  29. Send_Byte                                Sends one byte using SI pin to send and ! K3 s0 m9 k9 Y
  30.                                                 shift out 1-bit per clock rising edge9 k/ T- g+ e1 G$ e% S1 y, `
  31. Get_Byte                                Receives one byte using SO pin to receive and shift ; L  ~5 G$ P  E1 q  b6 }
  32.                                                 in 1-bit per clock falling edge
    - G- c/ K4 ^; @( v$ z
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    % w/ g# W8 K8 Z" H2 F
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high/ W+ ~( k9 ~- M/ j- ]
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    9 k) c3 V" `& `. D9 x2 m4 ^* {. E' C, r* b
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    " W3 h, H, b6 T! c* @
  37. Unhold                                        Unholds the serial flash
    7 i8 ^2 h; u4 Z8 o
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    0 t* W$ Q3 o% }; e
  39. UnWP                                        Disables write protection pin
    * I: b" \' }5 \( X- X
  40.   |7 G0 E* K1 A9 l- b
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    $ u# K3 T( e; C, E* F
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your! E* U4 Z1 C$ \! r
  43. software which should reflect your hardware interfaced.          
    : N; X1 s% u7 w& D8 z- V# O
  44. . s, W' Y4 m# }1 [
  45. 1 F7 t4 R7 p/ Q% x! w7 r) T4 g( N. M3 Y
  46. Device Operation Instruction functions:
    / F. N4 n$ W  Q4 V4 I% x6 R2 |. H
  47. : {3 h* m- Y$ ^' E% F
  48. Functions                                    Function
    8 Z; e. ^8 K7 ^+ O
  49. ------------------------------------------------------------------
    8 q  m# B2 X1 Q8 D" ]" o
  50. Read_Status_Register        Reads the status register of the serial flash
    7 g0 y) t& [! }; s" V
  51. EWSR                                        Enables the Write Status Register
    ' m  s9 X+ [1 x  {% L
  52. WRSR                                        Performs a write to the status register
    & b9 E! j7 ^. {% G! I
  53. WREN                                        Write enables the serial flash
    5 v# d& m% v2 u3 a
  54. WRDI                                        Write disables the serial flash  n* d: v  {  r4 r4 L2 R
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    + m- m: a0 m/ q0 e' ]% n) |
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming5 z. Y3 F9 X7 G' F* k
  57. Read_ID                                        Reads the manufacturer ID and device ID5 @' H5 y( u5 F) V
  58. Jedec_ID_Read                        Reads the Jedec ID
    6 P0 z1 q9 J4 b5 Q  C! ]
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    : u) H; H5 B- e9 e% d( x- M% S; }
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    & L% J# |4 W! d2 v7 y  \
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    , p$ {8 j* ^$ `
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
      D, q5 _2 I+ J1 \  V' ?8 o" K
  63. Byte_Program                        Program one byte to the serial flash3 T& O( S9 ^* E2 e# E& l& d, f
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    1 A( m& K, N8 l) X- }
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    - k  K* h! z) s
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    ! j! B' d9 W1 O& \
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    : D- Q$ U7 N) B0 J
  68. Chip_Erase                                Erases entire serial flash& x7 i7 n  _  r  W
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    # s; G7 K9 O4 Q' x
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    % G( Z$ Q9 I0 k- I9 S6 j
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    / E0 W  X% |9 |
  72. Wait_Busy                                Polls status register until busy bit is low
    $ d- Y$ Z1 }; U9 c+ }: w. E
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming2 O$ w8 O9 U) d' w7 Q$ i' Q! L' P
  74. WREN_Check                                Checks to see if WEL is set
    3 }( [1 V6 ^  T: P2 p( w; w2 l  Z
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set- a. r& a' J& \5 B, M4 D

  76. * P* r9 v0 Y" F1 M% @2 }

  77. # z$ }  N. R* I

  78. ' }4 J4 M* w* ^# ^2 v9 P% r
  79.                                                                      5 r$ g% S, ^" V4 G5 x
  80. "C" LANGUAGE DRIVERS 8 s" w; J# K7 ?# ~. F  r

  81. 1 ~6 T1 Z; j# M0 n
  82. /********************************************************************/* Q$ u# `/ Y# l6 Y3 ]
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */& M; y' y( [# l
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    0 o+ F: ]- D; s3 ?: z. |  D+ I( v' s
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */8 k: _0 E0 J: c3 |
  86. /*                                                                  */& W. a$ b! R; D& g2 }
  87. /* Revision 1.0, November 4th, 2005                                                                          */     Y4 ~: V1 H- S( B- F! u
  88. /*                                                                  */1 M* H7 ?* t, \
  89. /*                                                                                                                                        */
    2 F7 b4 a1 J9 c6 q
  90. /********************************************************************/
    ! M& u3 S  H) a; j, @8 L, E

  91. 8 r4 F2 E. C6 V* h/ M2 ^: r6 V5 M
  92. #include <stdio.h>! I, q+ G& F$ F& _: b
  93. #include <stdlib.h>9 H; A2 q3 h  F& m+ |$ r

  94. ( y4 x. V8 R1 N% f8 p5 b+ ?9 M. S
  95. /* Function Prototypes */
    4 k6 E; X$ I6 W( \- M/ p
  96. " s) T# G7 O/ {# j; ^+ ?6 H, O
  97. void init();
    $ ?, @2 I. a( h8 E# i/ R8 k! Z
  98. void Send_Byte(unsigned char out);" h3 L+ N& V& ^( u$ D
  99. unsigned char Get_Byte();1 k$ r( M& f6 N. }+ w. W
  100. void Poll_SO();
    4 K9 K0 S! Y6 p* X7 s" S
  101. void CE_High();4 t3 \0 K& \& x8 s' R( I
  102. void CE_Low();: _: B1 k4 Q: t' _9 d) Y4 T2 k
  103. void Hold_Low();
    6 d6 r9 P: R9 _$ a' a
  104. void Unhold();
    8 f6 T1 H/ ]- \
  105. void WP_Low();
    + D$ i) ~* Y: `+ }& L) m
  106. void UnWP();& Z, h! j2 W) q
  107. unsigned char Read_Status_Register();
    7 ]) r; A9 C  ?$ d$ T
  108. void EWSR();
    5 k; h* |& d8 P6 U. T+ {
  109. void WRSR(byte);
    " d) n; Z# }. A( }# `
  110. void WREN();& M! H$ G: m2 Q/ k" i" |7 O' F
  111. void WRDI();
    . C9 u8 p* j; b2 v* s8 A
  112. void EBSY();- v1 ]3 X+ m' {% f. c8 D1 G
  113. void DBSY();5 @) G+ Y  E4 u8 A2 T8 f# u) r
  114. unsigned char Read_ID(ID_addr);
    # i' T7 c* y) u2 a9 J/ h, O4 T
  115. unsigned long Jedec_ID_Read();
    7 A! T" ~, o. r7 E( d2 |
  116. unsigned char Read(unsigned long Dst);
    : y2 `( ^# C% {4 P
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    , G8 ]& j* H/ x- U- L
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    2 I8 T9 ]: T4 p: n2 B
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    ' D' B: X. O/ a9 |
  120. void Byte_Program(unsigned long Dst, unsigned char byte);9 J2 \9 I; t( \2 M2 d8 w5 e
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    1 L5 {1 j$ c. M* p- ]
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    , x' T& V$ t7 h! d
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);7 `1 Y& H9 Y3 C5 y* a' q
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    # G& R0 {8 D9 L- i! C
  125. void Chip_Erase();$ ^9 f4 s" q/ B: L5 s3 i& Q$ X( z
  126. void Sector_Erase(unsigned long Dst);
    5 M) \/ p! i' ?6 p$ k1 t: p, {8 e
  127. void Block_Erase_32K(unsigned long Dst);2 J3 @; D2 Y3 y3 D( a
  128. void Block_Erase_64K(unsigned long Dst);; c2 \8 T, e- }/ `3 O
  129. void Wait_Busy();# D' t1 u# w1 u
  130. void Wait_Busy_AAI();
    9 R: m4 x( z/ C) @" u9 E& m
  131. void WREN_Check();+ R5 ~+ {! ~. Z
  132. void WREN_AAI_Check();% L0 ]9 f% }6 A3 W; q* n9 ]# z

  133. * l# B0 z  r" w, L) n- s
  134. void Verify(unsigned char byte, unsigned char cor_byte);; M9 v# v- @2 y% B, B2 C+ }4 ?' \, I

  135.   _) u1 h' t+ J8 D& p4 N
  136. unsigned char idata upper_128[128];                /* global array to store read data */# F" U/ v$ }9 ?8 b& {2 q9 L
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    6 m$ X/ e( m  r- V, |( g
  138. ) b+ {3 @- ?" D! _# J
  139. /************************************************************************/
    0 p6 F, K" K: ^( q; m7 |4 \% C! b
  140. /* PROCEDURE: init                                                                                                                */) |( q- T! s( ~" q
  141. /*                                                                                                                                                */
    & z- p; r+ P8 H2 c4 o% p
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    + Z4 G7 ~& w  _9 y7 g' e
  143. /* setting up mode 0.                                                                                                        */* l' K5 t2 ~) K, w
  144. /*                                                                                                                                                */5 T5 r9 W: }8 W+ ]- ^. _
  145. /* Input:                                                                                                                                */5 B" N8 O( H& @
  146. /*                None                                                                                                                        */
    ( x: `6 q- d/ Q
  147. /*                                                                                                                                                */
    9 R( U& [( S1 s6 m" X7 G
  148. /* Output:                                                                                                                                */
    # \# S6 I: S" [. I
  149. /*                SCK                                                                                                                                */" L; n: f! I/ k. e: R
  150. /************************************************************************/
    3 x7 C" D, T1 S' P
  151. void init()  j' k" U# `9 @, D
  152. {
    ; h9 ^+ c; a: Q* Y0 |
  153.         SCK = 0;        /* set clock to low initial state */6 W7 q% s* a: A" r
  154. }
    + q3 }! b3 k2 x- R

  155. ' \8 z6 C4 H' L5 g: i
  156. /************************************************************************/. U& }1 @9 I. G8 k
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    # k% @, w! p7 d3 i
  158. /*                                                                                                                                                */2 B8 M" U1 M8 a, Z' k: D! o
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */  ?9 @' t/ m- _" n. t. d9 F
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    6 P4 k- g  B- N. G! e7 C( F' R
  161. /*                                                                                                                                                */
    % R! N( q( Z7 C. V' H
  162. /* Input:                                                                                                                                */
    1 C/ W% L3 l  m. W5 g2 G% @  z$ B
  163. /*                out                                                                                                                                */
    ' x5 _) H$ o* `+ t/ ~
  164. /*                                                                                                                                                */  M/ b6 \) u% M6 G) D+ u' c5 |& {
  165. /* Output:                                                                                                                                */
    ( ]4 f+ `5 ]9 q% b+ B) I, _
  166. /*                SI                                                                                                                                */
    ) d$ S# F0 A8 _% u
  167. /************************************************************************/
    5 K6 o" F6 s: m+ P
  168. void Send_Byte(unsigned char out)8 r5 x: d3 O8 w7 D& _- w9 p
  169. {7 O8 O6 Q7 R5 l' r. H( v! g/ \
  170.        
    & h9 K3 W$ e, M7 |; l; E
  171.         unsigned char i = 0;
    # [5 T, K. o4 ~
  172.         for (i = 0; i < 8; i++)3 f  N1 g1 a6 U1 i% p
  173.         {
    , c1 T' _9 {: @
  174.                
    # c' F9 v, F; ?2 i3 m. g
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    ' S+ ~+ b) k& l  a8 P. T
  176.                         SI = 1;
    , K7 n/ c$ E7 Q; e8 R1 r
  177.                 else
    , |4 |( F, A# m" L" c: O: S
  178.                         SI = 0;                                /* if not, set to low */4 k' J8 x& X7 J6 O) j( Z7 P9 {
  179.                 SCK = 1;                                /* toggle clock high */; F" H) K* B9 Y9 t3 G1 g$ O
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    0 u# r' J: c: o/ {2 Z
  181.                 SCK = 0;                                /* toggle clock low */
    & L4 y. U. ~0 z
  182.         }0 Y; w1 K- f  c* R. j* z
  183. }
    % e/ U+ j: J4 a
  184. , k+ _/ m; l* w# ]& H
  185. /************************************************************************/6 g6 \* _9 B3 r9 F* g2 k3 o6 S
  186. /* PROCEDURE: Get_Byte                                                                                                        */5 X" g/ i- [% w  {0 U, ]/ z* ]* f
  187. /*                                                                                                                                                */
    : l# Z* Z* r  [; g! ^) U0 \5 l- C
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    ( w& D$ w& R1 n( o$ s
  189. /* edge on the SO pin(LSB 1st).                                                                                        *// w1 i( I+ ~4 ]3 ?  B$ O  f# s' U
  190. /*                                                                                                                                                */' B( E+ n2 T. M
  191. /* Input:                                                                                                                                */
    * ~3 }3 c/ \" ^: k- B' B; L: U
  192. /*                SO                                                                                                                                */7 q; H( v0 i1 X! x
  193. /*                                                                                                                                                */
    7 n/ ^8 X- u# ?- R; g( M
  194. /* Output:                                                                                                                                */
    1 U! c) [2 G1 X. ?
  195. /*                None                                                                                                                        */
    2 D5 h: e3 f8 k$ B* g/ P) p9 W
  196. /************************************************************************/' [1 r: X# [; I- T% y  i1 z
  197. unsigned char Get_Byte()
    ) U  D# D# O( z' V0 t9 H
  198. {
    * Y( F0 ]! M7 q5 {( ~$ g
  199.         unsigned char i = 0, in = 0, temp = 0;
    9 M- b3 ~% d2 k$ o6 r% j
  200.         for (i = 0; i < 8; i++)- Y7 ~/ u* k& {% ~; ]
  201.         {( o2 ?! i& N4 H1 Z( k
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */# t8 ?( |1 G2 X: {; A; i
  203.                 temp = SO;                        /* save input */% q0 }/ _5 R# D
  204.                 SCK = 1;                        /* toggle clock high */; u( T( N- e# A# k
  205.                 if (temp == 1)                        /* check to see if bit is high */8 j( S: T) P. X4 g4 F) \
  206.                         in = in | 0x01;                /* if high, make bit high */5 b' L. ^+ b& a4 \& z+ e  N8 s
  207. ( f% C8 E$ u+ X! h) m
  208.                 SCK = 0;                        /* toggle clock low */
    ' a, \! [4 v" ?; O6 V6 f
  209. : l: }. t9 |0 Z6 n" E3 G
  210.         }
    " }! e0 e& I. Q+ Z! [* |2 G
  211.         return in;5 W, D. Q/ |: g+ ^8 p
  212. }
    & I" Z; _" N' g2 X8 C

  213. 7 D+ T: a& x  r
  214. /************************************************************************/
    " h0 C0 o) S1 j: r& ?$ x* Y
  215. /* PROCEDURE: Poll_SO                                                                                                        */* g% u( c8 C; S3 t4 u8 C5 ^# }
  216. /*                                                                                                                                                */
    / W  q  J0 u4 k& d  a
  217. /* This procedure polls for the SO line during AAI programming                  */  V7 V  l9 \8 w# K% T& T
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/0 c6 j& p2 b. c: T! s# l7 o& k
  219. /* is completed                                                                                                                        */* ]4 x7 ^- k: i" `
  220. /*                                                                                                                                                */
    , ?3 m& D& }3 w5 j+ W  ~1 h- v
  221. /* Input:                                                                                                                                */
    * V! z7 ~2 ~# }; e5 X* O
  222. /*                SO                                                                                                                                */
    # d/ K# t; R* P2 s, ~: H- }' g" R
  223. /*                                                                                                                                                */
    5 @+ O+ O: K0 q  i0 a
  224. /* Output:                                                                                                                                *// {, U$ P' _% G4 a
  225. /*                None                                                                                                                        */
    4 F* x+ z5 x" u3 T, d) i
  226. /************************************************************************/
      r9 `1 g! }6 |, z( l2 r
  227. void Poll_SO()
    & e1 F% M, N  N% c
  228. {
    8 J8 S' l% ^/ B! w/ @4 v& U( U" d
  229.         unsigned char temp = 0;+ l; D, R0 q( V3 j+ r$ z( t
  230.         CE_Low();
    , W% A) ]7 F" G! O$ z
  231.     while (temp == 0x00)        /* waste time until not busy */
    ' f; ]) ~; T" V, w
  232.                 temp = SO;
    ; Q% f/ \0 u' \. T9 S; Q
  233.         CE_High();/ A: O7 R% J4 e/ J) A
  234. }0 c& j1 v( @- R( l* }* D
  235. ' y' o7 j" T9 {2 d8 V
  236. /************************************************************************/
    1 p3 W/ O2 L- E+ E- b  X
  237. /* PROCEDURE: CE_High                                                                                                        */
    / C' \, \3 h7 B& f9 u
  238. /*                                                                                                                                                */
    ) l: L) U& @5 {
  239. /* This procedure set CE = High.                                                                                */
    8 o0 I; |- M3 C+ T, y3 a
  240. /*                                                                                                                                                */
    , v( v. q% o5 M, F4 F1 p7 @3 _2 P
  241. /* Input:                                                                                                                                */
    2 |- i0 j; p4 x+ G& k
  242. /*                None                                                                                                                        */! B: M3 x9 _: c! E$ Q1 y
  243. /*                                                                                                                                                */, @% \- x' Q& E$ i5 D5 w* o0 k
  244. /* Output:                                                                                                                                */
    9 g' X' s2 k# r% A
  245. /*                CE                                                                                                                                */$ r1 Z6 _  ^7 n7 U0 X& A
  246. /*                                                                                                                                                */4 u. y0 }0 s4 f0 m/ ~
  247. /************************************************************************/& |$ y3 o# O% W* p; h
  248. void CE_High()
    & r- A" s9 x: i+ ~: I; F1 X
  249. {. k6 z$ e. ]+ X- k
  250.         CE = 1;                                /* set CE high */
    : O) M% o# n/ K+ L2 i
  251. }
    ( L( A+ D8 n9 ^2 t4 A
  252. ' C6 M# E8 m. m( Q& m* ^0 P7 S
  253. /************************************************************************/
    7 @. x) B. ^2 G" z; {! @4 ~8 f
  254. /* PROCEDURE: CE_Low                                                                                                        */8 i/ f8 L( X3 J6 H: R
  255. /*                                                                                                                                                */  y* L9 ^' t& a9 Q# Y2 L8 f
  256. /* This procedure drives the CE of the device to low.                                          */
    / {  s* P9 L9 Z5 j; _, s5 r
  257. /*                                                                                                                                                */
    8 r* \9 g+ G% S% k* k
  258. /* Input:                                                                                                                                */
    5 o( D* V5 t' j" d: w( R3 [
  259. /*                None                                                                                                                        */
    # k) ]- }; y2 t+ @. a
  260. /*                                                                                                                                                */
    9 Z' {0 K/ V% s0 W/ }' P
  261. /* Output:                                                                                                                                */
    - ]' I' _0 K; C0 G* t" \& ~# F& h
  262. /*                CE                                                                                                                                */) {, S6 H/ \. O+ v
  263. /*                                                                                                                                                */
    $ _# Q5 S" o* K# q: K' [  q8 w  u* m
  264. /************************************************************************/2 S$ A* h* ^; R5 ~; L7 F' ]- @
  265. void CE_Low()
    ! U6 t+ d+ }" V/ I& U; Y) p
  266. {       
    ' B: }% l% l; y
  267.         CE = 0;                                /* clear CE low */
    1 Q7 u; Y! v6 j) Z
  268. }
    ! |; L' w8 y+ B: M! b$ h
  269. 7 l% A, l; m: |% P% i) O
  270. /************************************************************************/6 P/ F8 L5 P) ]0 _
  271. /* PROCEDURE: Hold()                                                                                                        *// J6 P" j6 G3 s9 _' e% g/ P
  272. /*                                                                                                                                                */
    1 L2 x" b1 ?+ q# _$ R4 S
  273. /* This procedure clears the Hold pin to low.                                                        */6 t' c6 L  U% S0 {
  274. /*                                                                                                                                                */
    1 O1 I) r6 c/ L& \
  275. /* Input:                                                                                                                                */! `& v8 H6 x2 ^
  276. /*                None                                                                                                                        */. V( e0 C7 a. J3 k
  277. /*                                                                                                                                                */
    * o8 w+ j/ C: H) k" z: H- V
  278. /* Output:                                                                                                                                */" ^, n/ s+ t6 o
  279. /*                Hold                                                                                                                        */
    $ n* j4 i6 `4 O+ v& z
  280. /************************************************************************/4 [3 |# T/ M3 s7 N1 }
  281. void Hold_Low()
    # E- S7 |8 ^8 a/ S, U6 X) U
  282. {
    . s* J9 r( m. G3 M# u2 e
  283.         Hold = 0;                        /* clear Hold pin */
    2 @+ j! v' g% R0 P
  284. }
    # ?' o2 o+ o( `$ c' O

  285. ) R' h. K' Q- `( s9 k
  286. /************************************************************************/% }/ `3 e5 I6 \  @/ c- G
  287. /* PROCEDURE: Unhold()                                                                                                        */
    5 M% B% G6 E4 e) y7 W# E
  288. /*                                                                                                                                                */) O! l% Y# J+ L1 a, V- F% u
  289. /* This procedure sets the Hold pin to high.                                                        */( y+ G; X% B% o" y; T
  290. /*                                                                                                                                                */
    - y, g9 n, S  a1 O; D. V. K
  291. /* Input:                                                                                                                                */; H# N; ]3 X3 K5 b  V1 u
  292. /*                None                                                                                                                        */9 E9 E2 d2 \$ n4 r
  293. /*                                                                                                                                                */
    2 {8 V& A) a* X- J  T4 M* O4 @
  294. /* Output:                                                                                                                                */' p4 l) Z0 P0 {5 S
  295. /*                Hold                                                                                                                        */* v, N& Q. ^2 t2 X; g/ B0 a
  296. /************************************************************************/
    2 h( s( y4 y  a5 m
  297. void Unhold(). W  N- i8 j2 @" J
  298. {
    # y. C. K* ?  n3 M5 p+ {
  299.         Hold = 1;                        /* set Hold pin *// g+ P1 l2 M( b9 c9 f9 b
  300. }4 R# |; T- R' j0 b( ^( Y+ X/ _

  301. ; B2 D% \- S# `+ Y2 K
  302. /************************************************************************/
    : C% ?! o4 ^$ j% b+ O
  303. /* PROCEDURE: WP()                                                                                                                */- f8 q; Y3 Q& F+ [3 p( |4 ^
  304. /*                                                                                                                                                */
    . v" s/ n" C& y9 D
  305. /* This procedure clears the WP pin to low.                                                                */" A) X3 B2 C6 O6 Y3 e
  306. /*                                                                                                                                                */
    9 U$ ?: T9 m" l% {
  307. /* Input:                                                                                                                                */
    $ c/ F/ F' {0 E! G  O5 O
  308. /*                None                                                                                                                        */. G( `- o$ @* k6 t( A% _) F
  309. /*                                                                                                                                                */% ~- h: d  B) U
  310. /* Output:                                                                                                                                */
    # w2 k3 t# o* G0 s0 e
  311. /*                WP                                                                                                                                */
    " i; A  L" ]' A/ ^1 O' X3 ^
  312. /************************************************************************/4 s2 x; N) T5 s( S- W, Y
  313. void WP_Low()
    : v5 A3 x' n) b1 w$ S: U
  314. {
    1 H4 T1 M1 G3 E$ {! E  ^
  315.         WP = 0;                                /* clear WP pin */5 X/ d# D( Q- \# r9 J
  316. }
    5 M2 X. O" m) y( x$ w( O5 D

  317. 0 A7 w5 R. a9 f
  318. /************************************************************************/+ q# r1 D1 u1 M- c
  319. /* PROCEDURE: UnWP()                                                                                                        */
    ! p% Z7 s5 V  c$ R1 T
  320. /*                                                                                                                                                */! R6 s: i* `9 V4 e; N$ {
  321. /* This procedure sets the WP pin to high.                                                                */+ r  H4 g2 V- k5 {/ m
  322. /*                                                                                                                                                */
    ( k0 t$ w, G: h2 {$ L2 {
  323. /* Input:                                                                                                                                */
    ; x& @# u/ R! C& X1 f
  324. /*                None                                                                                                                        */7 D2 o: G( y5 f# U' b; V  W0 T7 W
  325. /*                                                                                                                                                */8 K  W* ]' J$ S: m
  326. /* Output:                                                                                                                                *// v& |/ R* q  o+ G, o# a
  327. /*                WP                                                                                                                                */
    5 `* e. n# _$ D1 B) H
  328. /************************************************************************/- e* E: B" |% j$ a
  329. void UnWP()
    8 T* }6 b3 [/ e5 a9 G
  330. {+ T6 m* H5 d3 H
  331.         WP = 1;                                /* set WP pin */% k% }. U& e# F6 _' r4 j
  332. }
    " K+ S0 n( K: D0 R! p
  333. # A" F+ o  c9 Z+ P
  334. /************************************************************************/2 x& z2 |" O7 p2 v( |. L
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    8 `& }5 i" e6 Q, H
  336. /*                                                                                                                                                */
    8 Z# Y7 ?) c+ ?
  337. /* This procedure read the status register and returns the byte.                */' x" o6 Z# y1 F+ n) e& Z, D" A
  338. /*                                                                                                                                                */
    : t# i3 x& j( e' j! @: S  {/ j
  339. /* Input:                                                                                                                                */
    - G& F( I% i1 W2 ^
  340. /*                None                                                                                                                        */" [  B9 r: c' S; O
  341. /*                                                                                                                                                */
    ; q1 k$ B$ S2 `9 R* S
  342. /* Returns:                                                                                                                                */9 k: x" S) T2 s6 [) E
  343. /*                byte                                                                                                                        */9 I, ~7 k2 k' H0 V. a% \
  344. /************************************************************************/
    ( v( ]' \2 f! o- m
  345. unsigned char Read_Status_Register()) B5 m+ v$ \  H$ B4 f
  346. {  g4 ]3 e% ~' Z$ L1 ?1 q
  347.         unsigned char byte = 0;
    7 p" ?! p" \0 b4 s
  348.         CE_Low();                                /* enable device */
    " X) U# k% }: ~
  349.         Send_Byte(0x05);                /* send RDSR command */1 R- g& @, q8 ^
  350.         byte = Get_Byte();                /* receive byte */3 M: c* r3 f6 `4 `2 _
  351.         CE_High();                                /* disable device */' T+ H9 V/ H& e/ |! X
  352.         return byte;
    ' V; a( D/ p4 z+ c
  353. }+ x8 Q+ \: {4 g" q/ |# V, y
  354. 0 q& O7 E' t+ m4 p- Z! Y! e
  355. /************************************************************************/
    ; B6 s0 e( f, g: s3 R
  356. /* PROCEDURE: EWSR                                                                                                                */
    # K$ q3 s% {$ N( L7 ]- L( B
  357. /*                                                                                                                                                */
    ( Q# N* e' I0 o
  358. /* This procedure Enables Write Status Register.                                                  */
      U5 ]% \4 ~+ f* K& y1 U$ _
  359. /*                                                                                                                                                */
    ) z6 \% m' f! o4 K
  360. /* Input:                                                                                                                                */0 D% d; ^# C4 g  y+ T9 N
  361. /*                None                                                                                                                        */
    0 Q1 P9 m; }& }4 Q3 p3 i
  362. /*                                                                                                                                                */% H( `; ?5 `( q; Y, h5 Z
  363. /* Returns:                                                                                                                                */: E0 Q6 w$ |# ]: `5 L( J
  364. /*                Nothing                                                                                                                        */
    ( D& V2 b  p$ Q
  365. /************************************************************************/
    - f) z' T4 H0 L5 w% D0 H4 [( t
  366. void EWSR()
    - j  h' s7 u. O
  367. {
    * D2 ^9 \. I& t! p* z
  368.         CE_Low();                                /* enable device */7 `+ i  h( F* E2 w  h) ~% Z1 T8 c: W
  369.         Send_Byte(0x50);                /* enable writing to the status register */; ~8 p9 ^1 L  o
  370.         CE_High();                                /* disable device */- g9 l) k3 ?4 ]/ `! r
  371. }! `" r% }! y) N6 Q$ N8 _, Y

  372. & q& d. v0 n$ J8 t5 L: m
  373. /************************************************************************/  V: U; W! M$ E- p- `
  374. /* PROCEDURE: WRSR                                                                                                                */
    8 j! o3 W2 g3 T. a8 }- H: b5 K# C
  375. /*                                                                                                                                                */& O( A% Z# Z2 G+ z1 X
  376. /* This procedure writes a byte to the Status Register.                                        */6 t4 y4 ^+ f4 d) S1 ~  i, K0 C8 `, T- G
  377. /*                                                                                                                                                */
    7 J" A) t6 ]- L6 w- V( g8 o9 z
  378. /* Input:                                                                                                                                */
    6 i" q, \5 {+ ~: a6 a6 S) [
  379. /*                byte                                                                                                                        */- N5 e- M! h! a  o& f9 C6 _5 u
  380. /*                                                                                                                                                */
    2 J6 z, _3 @/ A1 S# r) x! w" M
  381. /* Returns:                                                                                                                                */3 h# G7 O& ?: Q* U- ?! l6 V8 u
  382. /*                Nothing                                                                                                                        */8 k( Q1 R2 x+ |
  383. /************************************************************************/
    * C. R# z+ `  x
  384. void WRSR(byte)
    8 Z7 i8 t5 ~& f: I* v
  385. {
    . c' @4 d3 Z# y8 h2 l2 G- Y1 M/ L3 w
  386.         CE_Low();                                /* enable device */) K# b. `7 c6 l) @3 Y8 G$ _
  387.         Send_Byte(0x01);                /* select write to status register */5 \* d8 x' I1 D
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    ( |" H1 R9 \, ?- I, K  g0 i  A
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */: N- [5 c" m5 u- \# D7 H3 U
  390.         CE_High();                                /* disable the device */' C3 L* Y( Z$ |# {. X- L
  391. }
    % F; n3 W8 z6 |( `5 ?- m4 O

  392. ( ]! }5 d1 f/ O+ |' e4 {& b
  393. /************************************************************************/
      T6 W. W% t4 t* @; G3 Z% u
  394. /* PROCEDURE: WREN                                                                                                                */
    ( l' K7 ^3 I# |# L+ U* N
  395. /*                                                                                                                                                */; R, ]5 k9 u; J# [2 [& |9 V
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */1 k5 C. o4 \* u. }5 q+ `
  397. /* to Enables Write Status Register.                                                                        */
    # E3 n. ~6 h' W' U; Z: D
  398. /*                                                                                                                                                */$ H% Y( K" U% ^+ P
  399. /* Input:                                                                                                                                */1 x' B+ d4 G+ m* x2 I. q" n7 J
  400. /*                None                                                                                                                        */& {0 h& u) D, N; B- L& X+ o" M
  401. /*                                                                                                                                                */
    - x+ q/ v% l) t  T
  402. /* Returns:                                                                                                                                */# {9 r$ z7 n( k2 d$ r% F
  403. /*                Nothing                                                                                                                        */7 I8 l+ K0 T$ B2 j
  404. /************************************************************************/9 Y5 u: {  U  B
  405. void WREN()" T- H5 D: `& _/ A' d7 W5 f
  406. {4 _+ ~/ w$ \. i- P$ j; G, t& j
  407.         CE_Low();                                /* enable device */
    . n8 \8 X/ K" ^! z! n
  408.         Send_Byte(0x06);                /* send WREN command */- w( H4 E4 W1 d3 N" Q: ~4 b
  409.         CE_High();                                /* disable device */
    3 u7 n/ D6 U# m0 a2 I( ?
  410. }3 \2 B0 G; y/ s  X" W8 b

  411. . s& t# m& K& C: R9 `) B& G
  412. /************************************************************************/
    # h/ q+ S! E8 K5 P" |. l  O2 n
  413. /* PROCEDURE: WRDI                                                                                                                */
    ( C0 e* H* D$ b  \
  414. /*                                                                                                                                                */
    ! s$ I& \2 [+ n- D, U
  415. /* This procedure disables the Write Enable Latch.                                                */
    ( l: X; d4 w/ A, q6 F. B
  416. /*                                                                                                                                                */! C" S: G5 Y5 t- B* z* W
  417. /* Input:                                                                                                                                */$ a$ i8 k  [4 z* H! b% T6 _
  418. /*                None                                                                                                                        */- J+ }$ z1 {% c$ Q. @8 z3 a
  419. /*                                                                                                                                                */
    ; B2 m  H; o' v  ]9 z& z
  420. /* Returns:                                                                                                                                */
    . K6 Q: K8 z2 Z1 j: z' ?
  421. /*                Nothing                                                                                                                        */3 z. h3 l+ D( Y, B) n% _; h
  422. /************************************************************************/  N, {" p! X1 }
  423. void WRDI()
    - J8 S4 O& V2 h$ r3 \0 C2 j
  424. {5 {1 O/ Z5 Z2 Y
  425.         CE_Low();                                /* enable device */: u  h4 W; b: D: k9 ~8 f6 O: z( k8 g
  426.         Send_Byte(0x04);                /* send WRDI command */: w! @& l2 L- H5 q3 R% m0 m. j/ L
  427.         CE_High();                                /* disable device */
    ' s* e  ^: [- i& o9 g/ G% D; N
  428. }
    ( n+ I- k$ b* r; x# A8 A( Y

  429. 3 {# T8 J8 T/ r# R" l8 i
  430. /************************************************************************/
    ( Q. n* ~/ y! a  h
  431. /* PROCEDURE: EBSY                                                                                                                */
    3 i6 `( d' ~, c5 X% }' Q; w/ M# n
  432. /*                                                                                                                                                *// m/ j- Q$ ?5 b) |
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */+ d+ e. n, x9 s3 r, {) v5 I
  434. /* programming.                                                                                                                        */7 x' ~: S1 C. n% ^" b
  435. /*                                                                                                                                                */4 L2 d$ ~# f0 q% V2 ?
  436. /* Input:                                                                                                                                */
    5 \$ t7 {+ x* Z7 }
  437. /*                None                                                                                                                        */
    ; A2 Z& h/ t5 y9 Z' b4 h- O( b. w% ?
  438. /*                                                                                                                                                */
    2 C. L+ |- p. L, u7 I
  439. /* Returns:                                                                                                                                */
    $ z- J8 e' J4 @' ~4 O: s
  440. /*                Nothing                                                                                                                        */
    4 r5 x0 V# j9 u# s0 |
  441. /************************************************************************/' ~3 r3 K, @8 B6 z- ^/ |: X" f7 t
  442. void EBSY()
    3 O" ~  f& O3 u; \  r3 q
  443. {- g  P+ j: P! J2 L5 a6 L
  444.         CE_Low();                                /* enable device */4 P8 T' R4 J: K. k# L9 K2 \$ t
  445.         Send_Byte(0x70);                /* send EBSY command */
    ; D8 c5 y6 Z  D
  446.         CE_High();                                /* disable device */
    8 ^) ~+ O$ e3 y
  447. }
    . G; T+ R7 ~% i

  448. ; I3 y0 o  h/ O' s' I8 O0 ?; r
  449. /************************************************************************/
    : q3 m. N# B) n% ^5 V1 J
  450. /* PROCEDURE: DBSY                                                                                                                */: I- R0 N/ z2 ~* G9 ~3 s7 |3 P- s
  451. /*                                                                                                                                                */
      ~8 ?+ K, o, }3 N6 K
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    ! o$ J/ `) x& a, `9 k
  453. /* programming.                                                                                                                        */. }6 ?: g) n: W' M/ g1 K8 `: b$ P; P
  454. /*                                                                                                                                                */
      O& N3 X4 d7 h( T
  455. /* Input:                                                                                                                                */, a; e6 P9 a8 g; W: g6 b9 G
  456. /*                None                                                                                                                        */2 r. _" n2 A' S* q
  457. /*                                                                                                                                                */
    " k1 j' u2 t, h% ]! k+ W$ y+ d- V
  458. /* Returns:                                                                                                                                */: f: S/ L, E; U  ]7 x' {" M
  459. /*                Nothing                                                                                                                        */, {# l* u1 c. A% _4 R$ A
  460. /************************************************************************/3 ^1 {+ A! l, d
  461. void DBSY()) O6 Q/ [) m! t5 i2 K: ^' ]6 _& f7 j
  462. {+ T9 P$ `: W: S1 c! V6 }- x2 S
  463.         CE_Low();                                /* enable device */
    5 c; _4 _+ R' W/ E6 E
  464.         Send_Byte(0x80);                /* send DBSY command */
    ' n5 V6 L% G1 e" N, X
  465.         CE_High();                                /* disable device */) o& [- G, s# T4 ^3 {. S
  466. }8 n$ f9 j3 x9 z( n- g3 y$ w) I/ W

  467. ; J9 ^, ?9 d& U: n" K, w
  468. /************************************************************************/
    , t  L+ I+ \7 A& e. u; D
  469. /* PROCEDURE: Read_ID                                                                                                        */9 {6 J, C6 [2 y& P4 {# g
  470. /*                                                                                                                                                */
    5 A! O2 p+ ?8 G
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    5 m/ F8 F6 x4 c5 ?( g+ `$ V
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */! B- _; ?" |) D$ \
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    4 p9 I0 h2 Y3 ]5 J. Y: h7 u
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    " h" c& [  z% r/ |2 g! s# b
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    , o9 P- \2 D0 l/ C
  476. /* variable byte.                                                                                                                */
    6 i5 o% |2 Y& @. `7 z9 s
  477. /*                                                                                                                                                */5 h, t" q: q) [, s$ F# m* E4 o1 D: M
  478. /* Input:                                                                                                                                */
    + \4 g5 t1 g' p$ q  d5 c' i2 {2 b
  479. /*                ID_addr                                                                                                                        */
    6 C+ q/ q9 c# p6 ]7 @5 E. d6 L" O
  480. /*                                                                                                                                                */
    / [' r! e) p0 a6 U, _8 S
  481. /* Returns:                                                                                                                                */5 v! I5 o  j5 z$ f) k8 ]
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */& O8 W, w! u- S7 L* Y/ L% D' K$ h# V' L
  483. /*                                                                                                                                                */
    0 S$ u. [* m* E" e! ^2 \
  484. /************************************************************************/5 \$ }+ D! r; D1 g' n% }* T
  485. unsigned char Read_ID(ID_addr)
    ) V# V% B- X5 R4 h1 V
  486. {- B" Q! o! }: u2 h
  487.         unsigned char byte;% {, @6 O$ k$ [
  488.         CE_Low();                                /* enable device */- y% H% T$ n7 P4 N
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */' y; ?- W- s1 Z+ @$ _
  490.     Send_Byte(0x00);                /* send address */$ W! r5 k& J+ ~2 R2 ~" I
  491.         Send_Byte(0x00);                /* send address */
    6 x3 U: B: u/ E( E: g
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */& U: M- O  o% U' A- a" G. N
  493.         byte = Get_Byte();                /* receive byte */
    7 P! Q( C) W% J. v: ?( N5 R
  494.         CE_High();                                /* disable device */
    6 ]# I" N5 c& o3 E$ }8 n
  495.         return byte;5 B! P2 H; F) W) w% W" }
  496. }
    ( w1 X6 _3 U2 ?* n) X9 r( L
  497. ) h$ ^% d/ b* y0 k+ m5 H1 z6 l
  498. /************************************************************************/9 M1 P/ c& t# {
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    ' T1 m+ e* ^. y; b9 }  x0 ?0 {
  500. /*                                                                                                                                                */% M6 a' H2 ]: k( j$ L4 h6 [, l
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    / s, ?% e# H4 g! S8 G4 b9 G
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    . R" e0 O8 l7 H" F5 ^, n
  503. /* Please see the product datasheet for details.                                                  */# Y5 F- [* V( X: Z
  504. /*                                                                                                                                                */6 w4 L: e; H& U
  505. /* Input:                                                                                                                                */, I: }- f# k0 G; e/ v* a
  506. /*                None                                                                                                                        */! z- O  s) W; }- {, ~! L+ d
  507. /*                                                                                                                                                */$ \# J' Y1 `; f" U: G% }! h
  508. /* Returns:                                                                                                                                */
    2 m; Z, `# }# t1 P6 g! ?6 p
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */. q2 d5 R7 _- t) P
  510. /*                 and Device ID (8Eh)                                                                                        */
    9 x9 |6 w  }9 M# @6 y
  511. /*                                                                                                                                                */4 o2 n( R  b% X( u2 g
  512. /************************************************************************/
    ) Z: y$ e* p+ {2 O* |5 T
  513. unsigned long Jedec_ID_Read() % O' u- X$ c; u4 S( b0 K+ e
  514. {! [: A6 L5 \7 j3 T6 r1 a
  515.         unsigned long temp;
    ( o# N. w% r' W1 j' ?
  516.        
    , R% [9 W# `  o1 _' o
  517.         temp = 0;/ J4 S- V7 L( z% T6 y* T# z
  518. 0 P& g. g2 e: i! j6 p# k* W
  519.         CE_Low();                                        /* enable device */
    9 ^8 H* f/ U9 a5 q6 i/ y4 S
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    + ~! ~" `5 R! Y, g3 q
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */! G1 l% b, W7 h$ V0 u
  522.         temp = (temp | Get_Byte()) << 8;       
    / X( \4 G" l4 Y5 v+ N2 `- E0 G
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */4 z6 v2 T% z9 ?; {! \# d% X3 f
  524.         CE_High();                                                        /* disable device */
    ) [" V+ m: O, Z& v$ `

  525. . _+ s2 Y6 @) \$ V( \
  526.         return temp;
    5 i* @! }+ R& ~+ V6 n! J
  527. }
      D9 j, V6 S7 T8 Z: e7 \
  528. 2 t4 }7 h& o/ b, q" Y. P
  529. /************************************************************************/
    # Q; P7 S- z4 G& x. h
  530. /* PROCEDURE:        Read                                                                                                        */
    : W+ u$ m: d; i9 O9 E
  531. /*                                                                                                                                                */                ) d$ R) {4 p+ c( L
  532. /* This procedure reads one address of the device.  It will return the         *// m) Q3 F) h" _  a
  533. /* byte read in variable byte.                                                                                        */2 |% W# [/ `: @4 d; |: h, }
  534. /*                                                                                                                                                */. `, B2 K; x" M$ I
  535. /*                                                                                                                                                */
    3 y5 p3 K; I) T! n
  536. /*                                                                                                                                                */
    ( [' |' D- o2 F! f8 x: J; b
  537. /* Input:                                                                                                                                */7 s2 F( G) _8 m
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */; p0 d. a9 J+ ?( Y9 X1 n. l
  539. /*                                                                                                                                      */( H2 O+ t9 _1 x
  540. /*                                                                                                                                                */
    " F/ q4 j, S& B) A9 ~
  541. /* Returns:                                                                                                                                */' q! U* Y" o9 E) |  X  Q
  542. /*                byte                                                                                                                        */
    " o3 Q" e. r1 j) k) I  C* [; p
  543. /*                                                                                                                                                */% a) b% R9 [; r* P; m8 x. x
  544. /************************************************************************/$ f/ Q' o( y  O8 A6 h' o* e
  545. unsigned char Read(unsigned long Dst) ; c) [1 I) _9 o$ i# T
  546. {7 L: M  _& u1 A
  547.         unsigned char byte = 0;       
    , N3 Q3 \6 W$ ^$ F5 i% t
  548. 0 r3 A' _+ l% {) @; G2 U# @6 u2 z0 m
  549.         CE_Low();                                /* enable device */
    6 g% j( E( F& i6 j
  550.         Send_Byte(0x03);                 /* read command */
    ( ~$ D' b3 ]" m2 @. H: A3 Y
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    " [) D# m6 e# i' q- y
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % O! B: G6 Z0 F4 y1 C! j
  553.         Send_Byte(Dst & 0xFF);: l3 Y) y. @6 d1 |9 C
  554.         byte = Get_Byte();( G7 f& Y) i9 A$ ^7 w
  555.         CE_High();                                /* disable device */8 \& U% U; A1 F- P: |: o2 O5 i; J
  556.         return byte;                        /* return one byte read */# c; H+ m$ }  z6 v4 R
  557. }( Q8 @0 a4 S; c4 t* v5 T

  558. 2 l3 ^8 F, ]! E' q! e: h
  559. /************************************************************************/" D' E4 Q6 d0 |4 S7 C' M: h9 g
  560. /* PROCEDURE:        Read_Cont                                                                                                */. g0 V6 `: `/ m8 \
  561. /*                                                                                                                                                */                1 K# G6 ~; ]9 J0 [. L6 w3 U7 G# |0 y
  562. /* This procedure reads multiple addresses of the device and stores                */, L! \; B# U/ E4 x# `( H8 v
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/9 W1 z5 n- Y3 y+ {( b( B
  564. /*                                                                                                                                                */
    0 L# Q$ q* I2 c  J( o6 u
  565. /* Input:                                                                                                                                */) u* o0 Q- R: |5 f1 W1 F
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */- ]' L! n( M6 V
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */* Z# G9 v' w- d. e, p( S0 d' n# \
  568. /*                                                                                                                                                */
    1 i' p/ a0 z( }
  569. /* Returns:                                                                                                                                */% \4 i/ Y% }8 W& H* N" }
  570. /*                Nothing                                                                                                                        */
    - ^4 e1 Q1 f' |6 ]' M
  571. /*                                                                                                                                                */# @6 o3 y* K, P
  572. /************************************************************************/" Z& U/ |- v3 m* n+ W) z
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    - l( Y  G$ v7 u* U5 R, Q  T. F
  574. {' K) W0 r% t+ P. V" n% |1 W
  575.         unsigned long i = 0;
    7 Y' j: p+ D% ^& y- H
  576.         CE_Low();                                        /* enable device */
    * v8 G- Y( `1 b  z1 {5 H
  577.         Send_Byte(0x03);                         /* read command */
    ( M' ^3 N0 C' r6 m! d4 q+ b1 j- t
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    8 Z, H% H( z1 ]9 K
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    # v* u- d) ^2 _& t
  580.         Send_Byte(Dst & 0xFF);, v6 o$ K0 r) u& o
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */7 z  x3 ]; d0 E) t. m
  582.         {( C# t  O, ?* w7 j2 X' ^  ?) X# ^
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */" b$ i) [! Y) z% c3 u) ], H
  584.         }
    / H- [, ^) P7 F! d- E6 [/ x( k9 E- g, Z* h
  585.         CE_High();                                        /* disable device */
    / @5 l& Y: C4 g+ Y  R

  586. ' B) b% l: W, ^/ |9 v" u6 w& [
  587. }8 x& _! t% x: e9 T: R

  588. ( P; O$ ?4 A7 Q3 U* i& O1 q# x
  589. /************************************************************************/7 q7 P2 ]3 o$ E1 X
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */( q# X# [0 F' ]/ {8 @6 D+ n' n
  591. /*                                                                                                                                                */                . v& a( w, g' b0 _2 u
  592. /* This procedure reads one address of the device.  It will return the         */
    ' z8 S0 A8 w4 d" U2 `! U
  593. /* byte read in variable byte.                                                                                        */( }3 h+ l% y; |$ u! Q8 h
  594. /*                                                                                                                                                */6 i: X4 \4 y5 t" a$ B
  595. /*                                                                                                                                                */
    ; T8 ]6 s& f6 B4 h! Y2 z. X/ a/ U
  596. /*                                                                                                                                                */5 n4 p9 F3 T1 n9 A
  597. /* Input:                                                                                                                                */
    - I% d$ ?' ^% m/ l- a
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
      |6 ~) C8 A- u; M  s" G, Q* L, J" b
  599. /*                                                                                                                                      */( I) O7 Z  h  O) l- Z
  600. /*                                                                                                                                                */
    ) w& A/ l; T( s: u
  601. /* Returns:                                                                                                                                */! W+ P2 |# y4 R( x6 o* @
  602. /*                byte                                                                                                                        */
      D* |: ~' |! J/ b' X  X
  603. /*                                                                                                                                                */6 F5 j$ e( p6 u" @3 I
  604. /************************************************************************/% J$ i( f8 \- [% E- X
  605. unsigned char HighSpeed_Read(unsigned long Dst) 6 y/ Y7 g5 G, R1 O' f: Z2 E4 I! p0 ?. S
  606. {
    " R2 r) R" U, L! g% d2 Z- r
  607.         unsigned char byte = 0;        # p. F4 @, j4 K1 u

  608. * q9 F  U% s% y- O  r. D- r
  609.         CE_Low();                                /* enable device */7 w0 U$ u$ l# v0 c' i% ^9 O
  610.         Send_Byte(0x0B);                 /* read command */
    / B4 C" X$ R! }* ?" E3 b- f
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    + D3 H: c3 j( \
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    . Y# R% j3 W0 d$ e
  613.         Send_Byte(Dst & 0xFF);
    * `7 }4 I: ]* b  N( H" _, G! w
  614.         Send_Byte(0xFF);                /*dummy byte*/
    $ m0 x  c% [. a
  615.         byte = Get_Byte();- G9 Q9 @8 d& y1 D- J: v
  616.         CE_High();                                /* disable device */
    0 G( X! E. C$ R* [+ `
  617.         return byte;                        /* return one byte read */& S1 I  b8 A( O- {# ]! e
  618. }
    - I: d( B* G3 r- |! q: [; ~
  619. % S( o. O8 j5 n. v/ w0 X# U
  620. /************************************************************************/
    $ d7 M$ U( R! `
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */
    2 U5 @8 B; E2 A6 A
  622. /*                                                                                                                                                */                0 n+ ]0 s3 @. [7 N/ G
  623. /* This procedure reads multiple addresses of the device and stores                */  E: }; t% i2 O& R
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/; y/ b  f8 t/ N9 o; p9 W
  625. /*                                                                                                                                                */0 S: X* s* i: v% [
  626. /* Input:                                                                                                                                */
    . O7 M& P2 R" p" A* M) K$ {( x
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */& M+ N8 a- F/ U( R* B9 w
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    * R! C6 r4 s, ^% @9 I5 |1 ]& k) y
  629. /*                                                                                                                                                */
    4 t0 b4 B' a- l% n
  630. /* Returns:                                                                                                                                */) L9 V4 s5 S3 x: {' x8 m  J' Y, o
  631. /*                Nothing                                                                                                                        */
    3 r( E2 G5 K7 P. _/ Y0 e
  632. /*                                                                                                                                                */! I$ {  M0 p0 a
  633. /************************************************************************/1 {, P) C+ v" o1 R
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)5 X% f8 d; Y9 \% J$ Q
  635. {
    + b7 V- d+ c3 R" N; v% Q* }3 o: y; ]
  636.         unsigned long i = 0;0 u$ o6 Z8 M* }2 h
  637.         CE_Low();                                        /* enable device */- R6 W/ }. f5 M0 K# c' s! U
  638.         Send_Byte(0x0B);                         /* read command */1 j; O/ @9 t2 t$ [' ]. ~. H
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */( F- d, v9 w; E: E
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));& a5 ?0 P- x& X: k
  641.         Send_Byte(Dst & 0xFF);" n9 T: b! _( M2 @7 A' p% Q& V
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    ' h! @) D) p! A: }
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached *// A+ J: s2 ?  Z! }2 @" j
  644.         {) D5 M. n8 g& {) N$ ^  @
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */* E% X9 j% c& s4 {! G) H
  646.         }
    2 F' ^( ~" D- }6 W7 R  V2 a3 B
  647.         CE_High();                                /* disable device */
    7 g6 y7 r9 N8 o$ |/ r
  648. }$ n. T0 n5 v* j6 l* e
  649. ; c1 o9 b% m0 B1 u( ]
  650. /************************************************************************/
    & l* N; g& R' s$ F( V2 W; w4 C
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    - u; C" i* Q' [/ _( }0 S" U9 I" @; {
  652. /*                                                                                                                                                */
    5 }' M) u- j, {, J- V2 D
  653. /* This procedure programs one address of the device.                                        */% g3 T% ]; P8 j( N& B: r
  654. /* Assumption:  Address being programmed is already erased and is NOT        */; L* ^9 L3 L" U1 X8 I: U
  655. /* block protected.                                                                                                                *// m* E; t  l* A8 B
  656. /*                                                                                                                                                */9 d1 ^( P7 a2 w! ~1 U
  657. /*                                                                                                                                                */& x) _! p6 B2 m
  658. /*                                                                                                                                                */
      G# p/ L  r- z8 z% g% c$ R! C
  659. /* Input:                                                                                                                                */
    6 x; p8 o( w2 S% r4 Z
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */4 ~1 F& R6 v) x
  661. /*                byte:                byte to be programmed                                                                */
    8 C4 U  o7 J; V- |" j
  662. /*                                                                                                                                      */% p+ Z. ^( P: g" y- s
  663. /*                                                                                                                                                */1 V! `: M' G' U& b' A( I' I
  664. /* Returns:                                                                                                                                */9 ~& M% L  {& }; P. e
  665. /*                Nothing                                                                                                                        */$ C9 [+ e  ~: a% e  l$ _/ U! X$ l
  666. /*                                                                                                                                                */
    4 O- ^' W; l" B2 h7 M
  667. /************************************************************************/
    , n5 B* Q6 S4 j9 b% a" ?
  668. void Byte_Program(unsigned long Dst, unsigned char byte), o) c) M: o, p$ O% p/ B; Y
  669. {5 @5 @' K7 g) G* F1 F8 J
  670.         CE_Low();                                        /* enable device */
    3 C  \8 L; i" ^6 z6 w  }
  671.         Send_Byte(0x02);                         /* send Byte Program command */+ ^  Q% T  F- u1 k: F
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */9 Q/ U) t2 n; T6 @
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
      ^! B& v: ]) L0 ~+ |
  674.         Send_Byte(Dst & 0xFF);; Z2 y( L: Q& ]
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    + b# j, E/ |, Y2 d- c( n
  676.         CE_High();                                        /* disable device */0 B+ {" @% a- ]1 h0 R+ R
  677. }3 J7 U5 ^4 C( n' H1 M: a( i% b
  678. ; C$ Q; w2 U2 }4 p. Y' ^' Q% k
  679. /************************************************************************/
    2 \" ?5 @/ H! C4 U6 a6 O. T( r
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    7 f( f& ^* u6 n: }! I6 v
  681. /*                                                                                                                                                */
    & ~* q8 P1 N7 x% @
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/+ u4 r7 ]: t- z
  683. /* the device:  1st data byte will be programmed into the initial                 */
    * I/ g, s+ m1 T' F" L
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    * h! ^5 M8 a/ S  e4 k0 V
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    6 m; V2 c$ t; ~5 b2 d
  686. /* is used to to start the AAI process.  It should be followed by                 */0 C$ v0 Q" o2 ]) M
  687. /* Auto_Add_IncB.                                                                                                                */
    7 U0 V. `6 A7 o' y' \: y
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    , `, D4 ]* ~! C  c+ `, [. b5 G$ N
  689. /*                                block protected.                                                                                */! x" P) G3 T! l' F! u4 K; _1 L, B8 u
  690. /*                                                                                                                                                */
    ; ]% x) V/ \" \% @
  691. /*                                                                                                                                                */8 q# b2 e& J9 x& ^$ Q; ^! Y3 W
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    & j  H$ r9 P6 @) W% ]
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */6 S. {2 i  d& K
  694. /*         unless AAI is programming the last address or last address of                */: t% f! c4 u  U* T' R; s0 W( L8 }& m
  695. /*          unprotected block, which automatically exits AAI mode.                                */9 f6 \* d5 w' N1 ~0 i- g  y! H; B' R
  696. /*                                                                                                                                                */4 @$ W, b  {' o9 _0 t& I
  697. /* Input:                                                                                                                                */0 U$ L0 w/ L# G9 G5 R( }  A% D
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */, _( c- t% m) ?" Y& ^
  699. /*                byte1:                1st byte to be programmed                                                        */
    6 [  Z3 A4 L: n7 d/ W) L
  700. /*      byte1:                2nd byte to be programmed                                                        */
    4 [( j8 `" D6 `1 U6 P5 X" t
  701. /*                                                                                                                                                */
    , ]# A: L& e3 j& C# @2 K
  702. /* Returns:                                                                                                                                */
    2 T$ m) L3 z, J. G
  703. /*                Nothing                                                                                                                        */) M0 `. k8 j! }: p% e
  704. /*                                                                                                                                                */  c6 l& B1 e! r; c
  705. /************************************************************************/
    ( v! p6 G. l6 a& H2 T* B
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    2 `2 P# J* X0 P6 t# Q, D( W
  707. {
    1 x% I' O5 U1 `0 t* w
  708.         CE_Low();                                        /* enable device */
    0 E; A8 a, B1 _: Y9 y, s
  709.         Send_Byte(0xAD);                        /* send AAI command */
    % Z/ B: L/ w8 E" o9 o# A
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */& Z7 K- o: A) `4 n- \
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));" n3 S# p  s; o2 M0 S. F: U
  712.         Send_Byte(Dst & 0xFF);
    % }1 @* G4 Y9 Q
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    3 C" k! p! Z& X3 `
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    6 t3 u* S4 d8 H6 N/ ~1 ^
  715.         CE_High();                                        /* disable device */- o  p( p9 l# e9 [
  716. }
    7 N# h2 `+ j6 N' q

  717. : G- o' R. }7 l( B& p
  718. /************************************************************************/
    ' G* N) i' O# l
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    ( R# Y8 z: W: C/ V! c
  720. /*                                                                                                                                                */
    : K9 T. j. x' l  v2 u* C0 r
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/, G1 x. g. Z$ @" c# w
  722. /* the device:  1st data byte will be programmed into the initial                 */
    2 m) h7 \8 \* u$ e; c5 i
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */2 R* f2 h5 z6 ^+ s
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    " ~6 G$ J' O  Y" A: [
  725. /* is used after Auto_Address_IncA.                                                                                */
    : x4 X6 p1 M& j' p
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    : e/ R$ d8 O  u
  727. /*                                block protected.                                                                                */
    , k! f) J/ K4 o% u' C2 h) C
  728. /*                                                                                                                                                */" K6 c" w/ _! ^1 P6 [8 r) M$ u
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    3 h& S/ W* p/ M! S8 G7 u8 t! e
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    + i6 K& @; C7 B, R# B5 Z5 I
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    $ M; g% _: j0 }1 P% |
  732. /*          to exit AAI mode unless AAI is programming the last address or                */0 g2 x# R. F* I& e
  733. /*         last address of unprotected block, which automatically exits                 */6 V" l, P/ z- m6 ?5 R
  734. /*         AAI mode.                                                                                                                        */
    - `; f! \/ r" z7 o: Z3 s" A0 \
  735. /*                                                                                                                                                */
    ( F* i  {3 {& K& ~# r5 y5 R1 A) t
  736. /* Input:                                                                                                                                */
    1 g, n# f0 P9 m9 \
  737. /*                                                                                                                                                */
    " L9 H0 a; g( Q6 z, [1 s
  738. /*                byte1:                1st byte to be programmed                                                        */5 F+ R& @$ V% G" Z4 B9 @/ C2 K0 t
  739. /*                byte2:                2nd byte to be programmed                                                        */
    - o# A6 x! }6 B. R  W0 X& w; W
  740. /*                                                                                                                                      */
    # y4 |3 f) u8 J# C% s/ l5 t) s1 v
  741. /*                                                                                                                                                */) z3 T8 g" `* _( h  ]- y
  742. /* Returns:                                                                                                                                */
    $ f6 t$ d0 N+ B1 P' X$ `' y$ d1 A! S
  743. /*                Nothing                                                                                                                        */: ~  h' Y$ x9 f% W) V
  744. /*                                                                                                                                                */2 F9 u; @+ _  V: y2 \- a
  745. /************************************************************************/
    ' [" J) ]) p( I! i/ B5 _
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    - C$ O) p# X  d* X( M6 c$ R; a
  747. {2 K: \( G6 E$ j& z1 O
  748.         CE_Low();                                        /* enable device */9 Z* m% |* M2 c
  749.         Send_Byte(0xAD);                        /* send AAI command */! D3 w, H$ G5 `$ v
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    ) p0 t. n; C/ R) t) U: a
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */% }3 h8 n, W6 @. r  g. n
  752.         CE_High();                                        /* disable device */
    " _2 H3 f( T9 \8 A
  753. }
    7 V7 A4 Z1 l. X% |1 j
  754. 8 @( \2 R7 \; q3 g* A
  755. /************************************************************************/% G& n, t" t. l* L: A
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */& A. @) e0 j( x- `+ x3 `
  757. /*                                                                                                                                                */6 B" o/ o  S. V9 X
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */- c7 }9 [- k2 P/ k' O/ @
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */1 m+ J9 _$ b6 Y% H  y
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */( a; _( |9 M! C9 F. l( c, C0 @
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */8 d6 H  R; c7 S- y) x
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    + ]& w) U* i5 j* g' b0 j, g
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */, w6 E. r1 Z5 a% n! e( _- m$ b
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */) g+ E( t- Y4 D& ^" }1 N# L$ x1 D+ P
  765. /* Assumption:  Address being programmed is already erased and is NOT        */1 y! P' @4 `2 ]6 s4 k
  766. /*                                block protected.                                                                                */
    0 L9 g1 t8 p$ }$ L' x  ?% E
  767. /*                                                                                                                                                */
    7 k9 [# k9 V5 b9 A# l  l; w7 E
  768. /*                                                                                                                                                */3 P& k4 Z& b1 S) e
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    + A  k) c4 J; L! B
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    1 Y  c* C$ a' \9 R2 s
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */7 h; J3 ^0 W  y
  772. /*          to exit AAI mode unless AAI is programming the last address or                */- H# |6 s3 U5 \6 d# i" e% J
  773. /*         last address of unprotected block, which automatically exits                 */6 f  ^" P- x0 F+ L$ y3 k2 c
  774. /*         AAI mode.                                                                                                                        */+ Y( A9 l9 ]$ ^, N! A; U/ D
  775. /*                                                                                                                                                */) e4 L) I4 f/ G9 q6 W  d$ {/ _% j  W
  776. /* Input:                                                                                                                                */) Z6 A5 C7 C9 B
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    9 \/ N5 s2 D6 k0 k& ~" C6 I8 h( x8 A
  778. /*                byte1:                1st byte to be programmed                                                        */, ]0 n! A+ i# r4 B1 ?- k% e7 C
  779. /*      byte1:                2nd byte to be programmed                                                        */% Z2 \: I$ s; Z1 l% x" I; M9 N0 M2 Z
  780. /*                                                                                                                                                */
    & g# d1 X' r3 X
  781. /* Returns:                                                                                                                                */
    , |- P& C; U8 ]1 F
  782. /*                Nothing                                                                                                                        */
    + ]1 D* r& x  W& F) ^3 f+ u
  783. /*                                                                                                                                                */
    ' g: Z/ v* _) y+ o/ s6 ]! y
  784. /************************************************************************/
    4 h  L# z% X5 C. a4 c6 h0 C
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)1 l) u: P) W: p/ T! V
  786. {  _6 V0 _* L! x6 A! V
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        $ ^) ?( ]2 t+ S4 c$ r% z
  788. 3 G3 c+ ]& e4 L5 r. U
  789.         CE_Low();                                        /* enable device */
    0 k) M  z0 y  [6 m+ F" E! ?
  790.         Send_Byte(0xAD);                        /* send AAI command */  }! `( W. P9 w, z; F2 _
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */3 B% k" `, T/ [7 @1 Y
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    1 |& s& V- \8 g$ M
  793.         Send_Byte(Dst & 0xFF);
    2 O1 x# y" o# f0 X4 X
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        % s4 y& A: S  l# B$ c' Q
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */) K% p! W7 [7 K8 Z4 v
  796.         CE_High();                                        /* disable device */
    2 X* h: \6 t+ \; ]$ G. q
  797.         # j) ~' c! o" v) G/ x! c6 t' A
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    7 d& G7 u% |8 p; z6 r4 f3 _' O
  799. # @  M" |  f$ R) U& |5 {8 ~
  800. }
    ' ^2 x3 Z2 F1 D1 w6 D& A

  801. , V: b& C; v/ O' v2 @  Q6 T2 B
  802. /************************************************************************/: `1 B8 m/ e$ p
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */, G" ]- y0 P- l- f& y/ Q
  804. /*                                                                                                                                                */& X4 u0 D2 H1 ^5 h
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    / J/ j) }, s2 @- g. Q+ c9 K
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */& b  F5 o9 |$ l- U; s: a
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    $ R. s5 m. x0 l4 [
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    * O; R: f4 c/ Y0 @& r) s' M  e
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    - {5 B2 }+ X: v( ~
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    2 \* p' H3 V  ?
  811. /* used after Auto_Address_IncA.                                                                                */
      E' v, x: ]0 @9 c" y* M, H
  812. /* Assumption:  Address being programmed is already erased and is NOT        */- U* i9 L) H2 o( U! }
  813. /*                                block protected.                                                                                */# I( C2 E0 Q7 p' Y* x+ z
  814. /*                                                                                                                                                */
    $ Z- d/ G" |' L% k  @
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */2 V7 w0 ], T5 y
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */% \+ [. v- q+ v) h/ q9 P
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */: K7 X# X. W$ j! h# d5 {$ M
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    " r( I* a; l) s
  819. /*         last address of unprotected block, which automatically exits                 */- |" ^9 o1 ^) m
  820. /*         AAI mode.                                                                                                                        */
    0 S' {3 N% O- h9 d
  821. /*                                                                                                                                                */% B' K  F# }- e6 p4 N3 O4 [: X
  822. /* Input:                                                                                                                                */
    ; O& C; @9 t3 v$ P8 {
  823. /*                                                                                                                                                */
    6 @# O7 H, [' R3 c
  824. /*                byte1:                1st byte to be programmed                                                        */4 y" k5 l$ W0 R5 u+ n% P
  825. /*                byte2:                2nd byte to be programmed                                                        */
    / M3 m: ^  J* ^
  826. /*                                                                                                                                      */
    8 z: b; t1 D+ L5 x, r
  827. /*                                                                                                                                                */# |2 q) o) f: j9 y. ^
  828. /* Returns:                                                                                                                                */
    5 U2 P* S5 G9 W0 j+ U# ~
  829. /*                Nothing                                                                                                                        */
    7 u7 U$ x1 W6 y+ [
  830. /*                                                                                                                                                */; U' v" e# R) ^- J5 e
  831. /************************************************************************/
    % @* n& ]& ^4 Q9 x
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    8 b( H/ y1 ~" R9 G: q
  833. {
    : \9 d* u+ G/ n) ^3 t; i. H
  834.         CE_Low();                                /* enable device */
    ( J  m5 |3 w! }& V5 E
  835.         Send_Byte(0xAD);                /* send AAI command *// U' a8 F1 v; K# |: \  E' `) T
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    6 A2 J! n9 P2 ~
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    $ k, T" B: Q6 `3 v* y7 w0 M
  838.         CE_High();                                /* disable device */$ x: d8 f* X# Y
  839.   c" h3 w8 S, W5 d* f4 ^
  840.         Poll_SO();                                /* polls RY/BY# using SO line */0 {& ]' c, u' I

  841. ! `# @# X9 w) u; D
  842.         WRDI();                                 /* Exit AAI before executing DBSY *// V. \$ ?$ [& e/ Q* k
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */7 e6 q5 H+ S& }! ~
  844. }
    / e' ~5 O  _+ S  ?. ]
  845. 8 V+ B! W9 t; b% I! n) X# }
  846. /************************************************************************/% q6 t, \6 N# u+ u
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    - `: k- L' o8 W- [* N; D
  848. /*                                                                                                                                                */
    0 s7 B) D- j8 w* y, Q
  849. /* This procedure erases the entire Chip.                                                                */
    8 D% ?. b3 M- a! {
  850. /*                                                                                                                                                */5 i, K) O0 y, N* ]
  851. /* Input:                                                                                                                                */2 J) M5 W! r% B9 i  E
  852. /*                None                                                                                                                        */
    8 J0 B, |& F. |
  853. /*                                                                                                                                                */
    0 s: s1 }/ u  n
  854. /* Returns:                                                                                                                                */
    $ h/ \! k: U. |* w% y) p
  855. /*                Nothing                                                                                                                        */
      l$ V' U( D+ o( d
  856. /************************************************************************/* j: [/ x$ E& \+ Q
  857. void Chip_Erase()7 D: d. Z7 b/ p
  858. {                                                * p0 V& h% B" @: ^4 J* j
  859.         CE_Low();                                /* enable device */) M6 [6 E6 r% N" V& K
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */' t% `& P4 [# k8 c( x9 `5 K7 P1 a' |2 U
  861.         CE_High();                                /* disable device */! S: ~% B9 Y% d5 E
  862. }. h" Y( l0 n* Z4 p# l

  863. + D' _7 F0 h+ q+ I# F4 \0 U6 p2 K" h. W
  864. /************************************************************************/9 ~( @: Y# N. g; `  a0 I
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    4 B# a$ v9 H& t4 N7 Q( `% k0 V
  866. /*                                                                                                                                                */
    ! {4 ^# n7 U1 c; v: _
  867. /* This procedure Sector Erases the Chip.                                                                */
    ; ~# O$ I3 b, r  M* W* r' X8 w& Z
  868. /*                                                                                                                                                */
    6 _. N1 c& s7 N7 e, z  \
  869. /* Input:                                                                                                                                */% u& X- S. P5 x9 C
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & A+ ?  @9 P1 l+ k) X
  871. /*                                                                                                                                                */! f; x7 L9 e+ ^3 A) r
  872. /* Returns:                                                                                                                                */
    ) L! b' O$ }& g; \) r2 E6 `
  873. /*                Nothing                                                                                                                        */$ [$ k$ q7 ~% U
  874. /************************************************************************/& {4 ]$ _8 k% t: c4 ~2 g
  875. void Sector_Erase(unsigned long Dst)2 t& C. w! t2 L% `, E
  876. {
    0 j7 |0 V: h1 }+ M. Q7 V1 H; ~* [7 z

  877. 3 x& v% T7 a( x
  878. 9 I; y8 y  `  p/ R  k! X7 Q
  879.         CE_Low();                                        /* enable device */
    $ m9 x% {) t2 o! z- d
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    ; W& x6 B2 e% K0 O9 B+ m
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    2 X  O9 S# S! W
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));( n7 z5 a  E# `) [' P9 ]+ D  Q$ t
  883.         Send_Byte(Dst & 0xFF);
    & z- ^' c) G- ]' L, \8 N7 s6 n2 y
  884.         CE_High();                                        /* disable device */
    2 L- ]( O0 }8 u7 o; G% Z; A% o+ z7 @1 b1 {
  885. }        7 {- I4 v6 B; B% m. r3 f; i

  886. 5 g" z6 J( I+ y
  887. /************************************************************************/7 g5 ]& s* F& \+ E, O7 G& j
  888. /* PROCEDURE: Block_Erase_32K                                                                                        *// \% ^6 N2 s: y! I( e
  889. /*                                                                                                                                                */
      P# {. y4 W9 o
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */1 J6 i: {! T6 D$ |: [1 D
  891. /*                                                                                                                                                */+ G  L2 U1 V. F8 }8 Q' m
  892. /* Input:                                                                                                                                */, H' S% u! L+ Q* V: U8 A
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    % ?  [0 e, A9 o; Z8 M
  894. /*                                                                                                                                                */: \! R4 d5 X8 ~0 D3 x
  895. /* Returns:                                                                                                                                */: W# S  w2 b$ e3 I' x
  896. /*                Nothing                                                                                                                        */9 W$ l8 G' L$ B
  897. /************************************************************************/
    / Y/ e/ h0 t7 u* Z$ a
  898. void Block_Erase_32K(unsigned long Dst)
    % Y8 ]8 ^& y. R- Z* z. {# X0 t" D$ U, g
  899. {
    % j8 e% J( ?% |" Q. Y+ I; }
  900.         CE_Low();                                        /* enable device */
    1 [* M8 |" I  g( f; y4 A. I
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */' i$ L9 _4 t9 y3 d, e
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */: X: t5 ?6 ~: n
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));! l+ v2 x$ y& d; X2 g  |( u  S1 A
  904.         Send_Byte(Dst & 0xFF);* I5 @$ ~# O! n0 r! }" ?. f& K+ k
  905.         CE_High();                                        /* disable device */3 W, o! i; v( H/ u0 w
  906. }
    " `3 b+ d# m0 Y& G! r

  907. 8 d4 X; }6 j% O) J; s# L
  908. /************************************************************************/
    " B) U' b2 `4 b7 B; J- ^. u( H5 k, e
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    3 V) w2 o1 Q  n5 n/ G2 v9 \
  910. /*                                                                                                                                                */$ E: R+ o' Y2 q. @$ \" \9 a9 y
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */# z/ L7 A% m, E5 P
  912. /*                                                                                                                                                */6 p/ N0 J2 U. o9 P4 c& G. E
  913. /* Input:                                                                                                                                */( b/ s3 G+ a6 b# G$ ~5 F
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */! M  w( p3 n% C$ g  a9 u
  915. /*                                                                                                                                                */4 \7 w- h$ H. n( o  r9 f" V8 c0 Z
  916. /* Returns:                                                                                                                                */
    : {3 F/ ?+ K1 w. n% A1 ~, t- x5 H4 M
  917. /*                Nothing                                                                                                                        */
    3 y7 w; I& q4 w6 a
  918. /************************************************************************/. I9 {, C' P* H( d5 u
  919. void Block_Erase_64K(unsigned long Dst)9 u1 o5 U( P% b  K- W$ q: `  W
  920. {
    4 G6 v+ D' H; u' p& Q
  921.         CE_Low();                                        /* enable device */
    # Q, C- |$ `" U& b; ?
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */; E( a8 ]$ e+ e  l) l# ~4 c6 j+ o
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */* C$ z" V9 V5 C5 o
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));! `4 {7 ~/ d- {+ C
  925.         Send_Byte(Dst & 0xFF);
    7 b( j+ G* w- S+ s! P4 Z
  926.         CE_High();                                        /* disable device */" `) G8 K( ^, V; q: P
  927. }
    5 j, U$ P4 ?$ r8 f; ?

  928. % |+ r9 o2 Z% L+ Q7 K
  929. /************************************************************************/9 y$ g" W; Q- b& _
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    2 m$ `' Y" j6 w( u
  931. /*                                                                                                                                                */! H5 h4 y: Y7 m( {+ x7 Z7 k
  932. /* This procedure waits until device is no longer busy (can be used by        */
    " o5 B1 n; M5 U4 V( H6 k* x
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    / X" h! M% e$ R4 r
  934. /*                                                                                                                                                */- G3 V# K' Z. X1 z' v2 l
  935. /* Input:                                                                                                                                */
    % o- V( j9 `: ~2 b; P/ i
  936. /*                None                                                                                                                        */
    9 z. v1 q6 V4 N
  937. /*                                                                                                                                                */
      K- s5 g( f* B: d" j6 T) z
  938. /* Returns:                                                                                                                                */
    0 N. F/ D! k" l- A  m) s, H
  939. /*                Nothing                                                                                                                        */
    0 P, {: K5 u: l( }3 n# R2 h# S; B
  940. /************************************************************************/0 e' t8 [  v. R/ O( \
  941. void Wait_Busy()7 @5 W5 R" p' _2 X6 |4 U
  942. {
    1 J% s8 V( y  |  U4 s7 n4 _
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */! }# p5 R% r2 q8 d( p
  944.                 Read_Status_Register();' L8 P6 n' Q! f: e5 w
  945. }
    2 J9 Y+ c4 Z/ c6 S* ]% T

  946. 6 }" ~; ]3 ~" p4 r
  947. /************************************************************************/
    ) a8 A- F; q- G  t
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */$ X  G) A) e5 y) s9 d
  949. /*                                                                                                                                                */. Q$ U# f. f, i% g
  950. /* This procedure waits until device is no longer busy for AAI mode.        */; g/ C; y) A& X* a7 ~
  951. /*                                                                                                                                                */1 F1 j: w: N* [
  952. /* Input:                                                                                                                                */. l9 r/ G# o. \! |
  953. /*                None                                                                                                                        */( D$ [1 U( J9 j+ `
  954. /*                                                                                                                                                */3 X# E( {* f, L! V5 V* w
  955. /* Returns:                                                                                                                                */7 y+ k: U  e+ U7 y, ^! z
  956. /*                Nothing                                                                                                                        */: z! Z' Y( R. _" `/ ~
  957. /************************************************************************/, e) H9 S* F1 x& z
  958. void Wait_Busy_AAI()
    . N2 a# ^. E& `" Z
  959. {
    * k  d5 v; |5 L' @  H
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    2 x4 u5 b; }) ?4 n6 D! ~
  961.                 Read_Status_Register();
    . G  ]8 _; Z- @
  962. }% D4 r8 t" U7 i: r
  963. : B4 X- L9 }3 J( k2 [
  964. /************************************************************************/  L- B- b! Z" }( d: ]2 r
  965. /* PROCEDURE: WREN_Check                                                                                                */9 D$ t) \% n' O$ Y' M, V" B1 x+ g* [
  966. /*                                                                                                                                                */
    6 ^1 V4 c+ j) g" j; A
  967. /* This procedure checks to see if WEL bit set before program/erase.        */4 s* `1 J) G7 u0 J2 ?# V
  968. /*                                                                                                                                                */& H0 ]2 p; q" r9 K/ U1 G  [
  969. /* Input:                                                                                                                                */2 l2 L/ j. v  M7 O
  970. /*                None                                                                                                                        */, M6 g) R2 t4 u& T8 `: ]& ^
  971. /*                                                                                                                                                */
    3 x" S/ W* y+ Z9 G
  972. /* Returns:                                                                                                                                */5 R" ~3 A, |2 x3 D
  973. /*                Nothing                                                                                                                        */
    1 x( @: x& g- \) e0 ~; o, o. Y
  974. /************************************************************************/9 G' v3 H% f5 B$ |$ y6 Q3 U
  975. void WREN_Check()
    " ~3 [; V% t8 x5 l0 u+ Y8 v
  976. {
    2 X! a% E) y" Q! h/ k8 R
  977.         unsigned char byte;
      r# j. K) n$ G3 A5 A. y- B
  978.         byte = Read_Status_Register();        /* read the status register */# Z) ?/ m, H1 @$ e5 E2 k" [
  979.         if (byte != 0x02)                /* verify that WEL bit is set */: A6 U3 k+ K- s4 b2 l+ l5 N
  980.         {3 T/ h, j) p! W, C1 O  i+ k/ M
  981.                 while(1)- I, |0 h# K2 r
  982.                         /* add source code or statements for this file */0 V: D7 o1 O; t/ G
  983.                         /* to compile                                  */& B) o" e( `" {6 a' t
  984.                         /* i.e. option: insert a display to view error on LED? */; s% ~) s4 u4 J7 E  _/ b
  985.                  
    6 B+ \+ W% H: n$ f6 G
  986.         }2 I' N+ T+ H! ?) F; _7 h; Q
  987. }/ X) G) ^( x; t  C0 i8 V
  988. / b& X% T# H( c4 S% ~8 s
  989. /************************************************************************/
    " d8 k2 W! r3 v  w; j$ R9 U
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */2 S' m6 @0 T5 j( f
  991. /*                                                                                                                                                */
    ! P. {9 y! N( r1 @2 t* ~
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    ) e* r. J+ V. H) r9 H  E, Z
  993. /*                                                                                                                                                */! Y' g4 K/ B& s
  994. /* Input:                                                                                                                                */
    1 S3 o# h0 O, @
  995. /*                None                                                                                                                        */
    1 e9 f  ]& _) p
  996. /*                                                                                                                                                */
    0 d4 Y; p  u: t6 z+ ^
  997. /* Returns:                                                                                                                                */
    , Z3 l/ `2 M+ K0 a4 Z2 b8 f
  998. /*                Nothing                                                                                                                        */
    6 m! R- y0 Y6 j6 C
  999. /************************************************************************/! K$ m& J3 S$ ^& u3 T* F) B" Y9 W
  1000. void WREN_AAI_Check()) |: _2 {0 I% j
  1001. {6 K& `* X& @7 o2 }( P" e! ]
  1002.         unsigned char byte;1 Q' N, y1 A* |7 Y$ \
  1003.         byte = Read_Status_Register();        /* read the status register */
    & {) r7 [7 r8 b% p
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */# P& O2 i7 W/ y$ [
  1005.         {
    - a) L* g) c; C  M+ r+ a2 Z
  1006.                 while(1)               
    ! G. c4 i' O- y( j6 U! n4 C
  1007.                         /* add source code or statements for this file */) @) I! u) J; b  ?2 o! x
  1008.                         /* to compile                                  */7 j& ~: j& z6 m* S; d% h
  1009.                         /* i.e. option: insert a display to view error on LED? */$ I# Q; x- [- |0 G) n4 r
  1010. ; I- k1 m9 }- H
  1011.         }
    6 G3 E8 q$ r3 z9 K6 W/ y9 i. k
  1012. }
    % q6 _" B# f" d/ m, i  @
  1013. % U; a( Y/ W5 [5 U8 r
  1014. /************************************************************************/
    : b3 K' |5 V9 n, J
  1015. /* PROCEDURE: Verify                                                                                                        */
    ; N: Y2 P" |- M, w$ A; @0 _+ F
  1016. /*                                                                                                                                                */8 y/ T/ N- U5 s2 |  H
  1017. /* This procedure checks to see if the correct byte has be read.                */
    4 D$ @! M) U; U" r) a
  1018. /*                                                                                                                                                */
    4 u, Z( b; D. A1 U' ~) p
  1019. /* Input:                                                                                                                                */
    % C5 m- b8 y% `7 N+ q
  1020. /*                byte:                byte read                                                                                        */9 k  J) _/ J5 N' x0 U5 ?
  1021. /*                cor_byte:        correct_byte that should be read                                        */( _1 g6 n3 b: y; m/ `
  1022. /*                                                                                                                                                */
    . F% s, E# L7 [
  1023. /* Returns:                                                                                                                                */9 `9 J9 x8 d+ W' _9 d- y. H2 b
  1024. /*                Nothing                                                                                                                        */
    " l  ^  T( P3 u2 y. C
  1025. /************************************************************************/3 w$ C1 L+ V$ w0 s' f6 |
  1026. void Verify(unsigned char byte, unsigned char cor_byte)" K! |# w0 `2 `$ @
  1027. {
    , u5 L  T/ j6 E1 D/ m
  1028.         if (byte != cor_byte). X8 @$ I$ q, h9 T
  1029.         {
    ( g' j) Z! A& g( @
  1030.                 while(1)0 A! m7 {2 c6 T. v( U! j
  1031.                         /* add source code or statement for this file */
    9 ~. p0 A% N4 A$ l$ P$ t5 g0 J
  1032.                         /* to compile                                  */, F: z8 l: ?/ k& B) `# l/ @
  1033.                         /* i.e. option: insert a display to view error on LED? */
    " ~! U! I' ~4 F  t8 }
  1034.                
    1 g3 r% v! {0 O/ w7 F0 y+ c
  1035.         }
    ! L5 U. Q1 o* \: l
  1036. }
    0 t: w' N/ H2 @4 d2 R8 L
  1037. # s3 q: v5 \; h7 g) U
  1038. . f* W3 V- u2 N! L
  1039. int main()
    ! i$ }) z0 m  P( x$ @: x4 m. d7 g
  1040. {; {/ F6 r" H0 P/ x2 J
  1041. / K. w, h; Q8 q* M! T/ L
  1042. return 0;/ Z4 o- n7 N$ z' F! L2 p
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
" `5 C% P) s' N# ^! J' Y$ `   main()
& e8 |+ u: y  q3 m+ }) c* j   里面怎么是空的呢?2 X( s$ {7 g) ?1 n" C. {
   发一份给我吧; i  n' S( ~8 E+ f3 G- v7 \
mail:luyijun2005@hotmail.com
. J/ l" F0 l! n2 S1 f咯。。。。
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。
4 v" ~- K. d# Q3 S2 I3 d" z7 Q, Z
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
+ A2 z& a  l0 Q6 [. G- n$ M6 hEC的代码在哪跑,你看DS的说明,每个EC都不同的。
+ A' i# ?# ]) dOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
7 A( b% P# {, Y9 c3 Z) Y) Z' J- F& j上面几个问题是你没看任何东西而白问。
2 _) ^, ]$ n. S! v6 W* F& q7 _
' w2 i  e$ G8 R- [* {至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

& o. {# i4 o8 p& q( S( r1 f关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
0 M  `* f2 n/ p, ?+ B$ Q0 q& ~3 y, v7 B6 Y# J
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”( \6 U; U+ n' v* a( Q6 a: y/ x
9 T5 [' U& n; G. d; t
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊.../ ~3 s* F" [$ ^. c

# {" d- L. ~: _! {/ |8 _# g不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
' l2 Y6 A9 |) Z" D似乎要把SPI能support 到最大,这EC chip应该有好卖点0 t8 Z( v3 h  V& L: R+ S
BIOS功能要不要强大,也就决定了SPI Flach的大小2 R" p% B: v( m8 M- E
我是这么想的~让OEM去决定要挂多大!$ Q+ T* J& L  ^4 C% i* i/ ^) y
如果我司有BIOS工程师就好了~哈
* f) y- U- k2 R( ZWPCE775应该算很新的东西,来看它支持到多大?
0 o; F% `# [' I7 |/ o
7 g( X. [5 N6 b. w$ U9 K7 S2 w另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte& z! ^8 D( {- i/ D0 ]0 m
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码., ?0 ]# U+ {' X- o, c

' p, A8 ^, D! X' l: U% Q, e, j( f这份driver收下~希望以后有用到! D2 S3 b  k5 c4 H, L
谢谢bini大大
2 Y6 a# w6 v4 S# ]0 F, v+ k# i5 [7 b/ {5 N
很新很新的新手,如有错误请指正 (准备看第二家的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()% w* Q$ ?: H3 g8 K
{0 C/ `& y: V3 {$ T  {$ H! O
        unsigned char temp = 0;/ L; j' M2 e9 j
        CE_Low();5 C) X% s1 p2 d$ T: |4 V% {
    while (temp == 0x00)        /* waste time until not busy */$ u$ r  [3 @3 L5 @$ N3 p% d* D
                temp = SO;5 n7 P1 p% E+ F" |  T' s
        CE_High();
: _5 {- J% h" j" y1 h}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
& D  Z% @0 l- H3 R2 c{# N  {7 |7 W, E, G
        ! H4 ?/ h0 q# t, K3 p4 H1 E% u
        unsigned char i = 0;$ J5 a; o9 B1 r0 G" l8 J$ c3 }
        for (i = 0; i < 8; i++)
0 N, V* j- t2 F8 g5 {( d0 S        {
" p  {) I+ k, N; V* C                8 c' |4 A$ X* O5 J8 p5 I9 c
                if ((out & 0x80) == 0x80)        /* check if MSB is high */8 A+ I+ F6 s% H
                        SI = 1;
* F9 f! Y4 y8 W8 |* m7 o6 ?                else+ V( v9 |1 \7 |6 V$ r! l6 S
                        SI = 0;                                /* if not, set to low */4 k7 x- E* v! C. |+ H
问              SCK = 1;                                /* toggle clock high */! ]$ H: x" O+ Q) V
   题            out = (out << 1);                /* shift 1 place for next bit */  a; Z) U5 m+ n) T+ r
                SCK = 0;                                /* toggle clock low */
! k$ o. v; A" e        }& m9 Z7 @) |: N1 ?
}, a0 _5 e8 E6 n3 Z+ r6 V$ X+ V
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-9 06:23 , Processed in 0.031382 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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