找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54920|回复: 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
    : ]! [. l+ w) q6 z' S! Y* Z

  2. 8 D% t6 s- a  Q' @6 m7 a& h
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory2 t0 V6 r# S7 f1 o1 P: Y& Y9 t9 G
  4. ( J+ h# |7 [+ l! Z, F
  5. November 4th, 2005, Rev. 1.0
    & c: w% Z  T& ]+ u! s1 V8 U

  6. . ~6 S( D' q# c- P' ]3 p8 p  Q
  7. ABOUT THE SOFTWARE" r- s. a" L) e- Y' V4 f+ p( p
  8. This application note provides software driver examples for SST25VF080B,: t$ c5 t% I( M2 ~& s7 \( b; q9 T5 ]
  9. Serial Flash. Extensive comments are included in each routine to describe
    ' O3 m# l# `) P3 U3 p  E) X
  10. the function of each routine.  The interface coding uses polling method * ^* A) L$ ^5 h4 n- v
  11. rather than the SPI protocol to interface with these serial devices.  The
    5 k7 K5 J! A, U& r
  12. functions are differentiated below in terms of the communication protocols! y+ v( |$ R8 Y  d! X1 M7 [4 u
  13. (uses Mode 0) and specific device operation instructions. This code has been
    , W! g5 y, Q7 h, Q/ M$ j% v. b
  14. designed to compile using the Keil compiler.
    3 A1 L1 n$ x+ Q/ ]

  15. ; t/ c8 q5 W: d( U6 n8 V; V, R3 [

  16. 5 Q" l5 l! |6 i; @" [
  17. ABOUT THE SST25VF080B
    ) S- F; K1 C! h( X& ~1 t2 [  _
  18. 4 [  h, T3 e" N0 _) k
  19. Companion product datasheets for the SST25VF080B should be reviewed in 1 I* A, Q4 n3 f) L
  20. conjunction with this application note for a complete understanding 8 L% ]. J; [) M" h; b
  21. of the device.5 [( q* ^% |6 s/ q
  22. 0 W. Q0 T7 ?0 {

  23. 0 X4 h% F% v) W- t& U
  24. Device Communication Protocol(pinout related) functions:+ |$ S, p# V/ g+ A) F
  25. 4 t, {7 Y4 @, p: _
  26. Functions                                    Function* _9 Z4 u+ O7 J' U
  27. ------------------------------------------------------------------3 c$ I& J$ O; M6 o, K
  28. init                                        Initializes clock to set up mode 0.
    1 x& p& {& h/ M# ~4 W
  29. Send_Byte                                Sends one byte using SI pin to send and
    2 s2 M# q# u9 n3 L7 f
  30.                                                 shift out 1-bit per clock rising edge
    6 B  r# G. @& C& ]( a
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    ; M; Q8 J8 \' [/ i3 |* B, e
  32.                                                 in 1-bit per clock falling edge8 U3 N, O/ B- d9 _; h  [, \
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming* J, R; k% F' z# b
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    ) {! f6 j) z. r# A
  35. CE_Low                                        Clears Chip Enable of the serial flash to low- _3 S$ w% |% {4 M# p
  36. Hold_Low                                Clears Hold pin to make serial flash hold0 C/ k- {! [8 `
  37. Unhold                                        Unholds the serial flash
    : \1 L) P" r! p- F9 \
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    5 d  v* j8 R9 J' T% E2 D
  39. UnWP                                        Disables write protection pin
    , m- H/ J6 B+ S, f6 J  }

  40. : z4 a0 n* [  C( k3 ]
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code1 k* Y/ ^& W& s# P2 I
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    ) z; E" C: B# T4 ]
  43. software which should reflect your hardware interfaced.          9 A6 {1 o: H; h% e
  44. $ @" Y; x" U6 ]6 _5 n8 C# P) P
  45. . k: O# R9 F* Q' t+ y9 J
  46. Device Operation Instruction functions:6 W. S' d& I) }) `

  47. # C- x( V( J3 I
  48. Functions                                    Function
    % G% k) g* T' q" d) [
  49. ------------------------------------------------------------------+ I  V, G0 h# |+ I2 N
  50. Read_Status_Register        Reads the status register of the serial flash
    : w9 M6 e0 [9 W4 j" S5 T9 I8 E
  51. EWSR                                        Enables the Write Status Register$ {3 ?# Q/ ?& m* v
  52. WRSR                                        Performs a write to the status register
    ( s; E1 f3 \0 @8 h& b7 c4 T
  53. WREN                                        Write enables the serial flash) F5 y' ?( `, |! x
  54. WRDI                                        Write disables the serial flash
    - |' g$ ]5 {0 M# z. F
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming3 X3 J( r/ F5 Q; w$ O
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming, y1 p6 n# f& f: J2 p
  57. Read_ID                                        Reads the manufacturer ID and device ID
    : i# d* v# Y. N  s
  58. Jedec_ID_Read                        Reads the Jedec ID+ N- B) s8 g2 `" {7 e% b6 ~
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
      [5 q' Z5 Z0 Y! q, P# T
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)0 S  Y9 j, [9 I% v7 w  w
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)5 {: T: A/ Y# I1 ~3 E) P+ I- p
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)* |' I. ^0 |1 e; u! A8 v4 }
  63. Byte_Program                        Program one byte to the serial flash7 L$ H  a( K& U5 D9 \% H
  64. Auto_Add_IncA                        Initial Auto Address Increment process: a  S) ]# U" C9 C; N: t
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    9 \5 P1 s2 p9 |' _2 Y9 o4 p
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
      I5 [5 G, T8 [: z+ C
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY" c2 i1 f, c! j( N
  68. Chip_Erase                                Erases entire serial flash
    ) R; A) }- K3 I8 L
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash3 W; V( G+ ?+ c
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash9 Z% v: g) C0 `. g, N0 b
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    8 j3 [5 X; Q8 D# ^! {3 E
  72. Wait_Busy                                Polls status register until busy bit is low; ^: H6 n5 C4 _1 I7 P9 ^0 y# ~
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming$ x( h% b! W% {
  74. WREN_Check                                Checks to see if WEL is set6 d9 q" M( o: D
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set0 \9 `; _9 e7 O) ?- R! b! q
  76. " y  S, A1 L, L3 t: E  J8 Z7 f
  77. 0 L" E4 n1 W+ X+ i% y8 O
  78. 8 L: b  M/ ~6 e# K
  79.                                                                      
    / o% U. H1 w+ {; Y, P0 U& f
  80. "C" LANGUAGE DRIVERS
    ( m4 H8 L# V1 D7 {

  81. # ~+ x2 `& A1 m+ h
  82. /********************************************************************/: j! Q6 j) I+ D$ B: V1 S9 v
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */) [: P/ |# n, I
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    ; ]/ Q4 F- d9 Z* v' x- y  R
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */" G! _  d$ u3 b! G# d# W* T
  86. /*                                                                  */
    $ b5 j' q7 q, K7 l
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    8 y3 ^$ J  {  O6 [1 o
  88. /*                                                                  */
    + S7 b+ Q. I) S5 `# Q
  89. /*                                                                                                                                        */
    $ P9 G$ k# D8 r
  90. /********************************************************************/
    " ^" }" I1 |) C9 K
  91. ! m4 ]: ?, b5 G5 V, F+ ~
  92. #include <stdio.h>
    7 o  R. B) s" b9 {0 A4 j
  93. #include <stdlib.h>
    6 W6 b) N2 L) ?/ u# n
  94. 3 `  V2 V- W" A# |0 m  J5 w$ z$ e
  95. /* Function Prototypes */6 B- ]0 G  U3 A

  96. ( ?. ^; W9 d$ _, Q% a. ]! f
  97. void init();" g( O% l1 U' z1 N9 F
  98. void Send_Byte(unsigned char out);
    8 ~6 h: g6 B4 g7 A/ ^
  99. unsigned char Get_Byte();- |1 q7 x9 f8 z3 w
  100. void Poll_SO();
    0 r5 \' B; p5 U, l! a" @! H
  101. void CE_High();
      K! l% F& g* e- b
  102. void CE_Low();
    ; S) I; i8 E' u0 [& y2 l. ]& M
  103. void Hold_Low();
    ; q- s; h6 t/ G) h: ~
  104. void Unhold();  }: Z( z* W& y: f$ i  M$ }
  105. void WP_Low();7 B7 T) T! A$ v0 ]
  106. void UnWP();9 M$ v# l/ j* z! Z4 l
  107. unsigned char Read_Status_Register();+ G# {3 q2 r- p& ^) R2 _' _
  108. void EWSR();
    & x) {; C4 r0 b" w; G# I
  109. void WRSR(byte);3 ^7 l0 i7 \3 X/ _8 J, Q0 V6 Y* A
  110. void WREN();; u" t, {: u& d+ l7 _) Z. s2 w
  111. void WRDI();1 r' A/ I* W: y" J
  112. void EBSY();& y7 A2 ?9 ~4 X1 i3 i2 [5 ^, K4 ~7 e
  113. void DBSY();
    + c( o! W) u/ m$ G3 H
  114. unsigned char Read_ID(ID_addr);0 T* {( |) D! u1 l4 V' c2 Q7 c
  115. unsigned long Jedec_ID_Read();
    4 o5 ?+ T9 {$ j9 j1 i8 z8 G
  116. unsigned char Read(unsigned long Dst);/ Z2 P1 k# _' d
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);0 L& D2 r: H9 d: u, a7 y
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    9 X( y; Y9 G. L/ k/ h/ y
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
      W7 l7 S2 Q8 H8 i3 d1 Y- [9 l4 ^
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    ) V; i8 c0 C$ [4 @1 o
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    * j" e! A+ @/ y2 J+ y# |" ]8 ~
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    0 [! ?$ C+ e1 }. B$ G( e( B9 y. c
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);$ T# `% d- m( l. e; H" w
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    - v7 f: X# q) x' Y; T& ~0 q. f
  125. void Chip_Erase();
    1 v/ W2 t$ w, O6 H0 M- V
  126. void Sector_Erase(unsigned long Dst);7 C7 z5 Q5 M; N, C
  127. void Block_Erase_32K(unsigned long Dst);
    , [, |. K! ?2 b$ x
  128. void Block_Erase_64K(unsigned long Dst);7 |/ G4 x; f3 B3 W0 e* x6 T
  129. void Wait_Busy();) F+ H" A# a/ d; ^" G
  130. void Wait_Busy_AAI();
    9 d7 Q% R" \3 F4 H- [
  131. void WREN_Check();
    ' D- K" R& L& h, z2 r" R" S
  132. void WREN_AAI_Check();
    * a: b/ p: `1 H5 o. r

  133. & n7 U% t0 y8 ^
  134. void Verify(unsigned char byte, unsigned char cor_byte);0 B- g( `0 Y# O1 G
  135. & o3 s# G* d, f  H) n
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    5 q) y: z% e, A7 z
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    9 E! n$ G) T# }6 @

  138.   L9 O7 `1 G: I1 G' L4 o
  139. /************************************************************************/
    % h/ F0 P' f$ N7 O6 B
  140. /* PROCEDURE: init                                                                                                                */5 O& q3 V/ O) j5 q. L$ c
  141. /*                                                                                                                                                */4 \+ a- X! U0 r+ J( a3 `# Q0 p6 |
  142. /* This procedure initializes the SCK to low. Must be called prior to         */4 f/ C0 n  X$ _" \( ~. Q" k
  143. /* setting up mode 0.                                                                                                        */
    . N, b# K& P+ y; g
  144. /*                                                                                                                                                */$ J7 {, b4 r. [# ~
  145. /* Input:                                                                                                                                */
    # n$ D: e# ~8 n8 U, @" w
  146. /*                None                                                                                                                        */
    3 L: {3 b6 Q  L8 F
  147. /*                                                                                                                                                */, |& D' {9 |1 H
  148. /* Output:                                                                                                                                */
    " _, |2 k; B( G9 Y" `
  149. /*                SCK                                                                                                                                */2 E# _. c. I* [4 X
  150. /************************************************************************/
    1 {+ P' E- S. r: ?! u) m
  151. void init()
    5 b7 r) r- O* C1 w
  152. {2 j" x" `/ L$ \3 ?; O
  153.         SCK = 0;        /* set clock to low initial state */% \  l) c6 h+ l$ M/ a, O
  154. }- q% I+ q& n  R7 |# y% Z
  155. ; T' F" T3 G! n! d
  156. /************************************************************************/7 |2 z5 a6 j- \( w9 A/ t
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    6 L) Y- ^: k- G2 t9 G
  158. /*                                                                                                                                                */. b. Y; d- y- g
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    0 f! ?9 \/ H5 t0 f
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    ' C6 g+ K4 \6 u' G; u
  161. /*                                                                                                                                                */
    * S; {5 ?2 b0 J) G
  162. /* Input:                                                                                                                                */
    6 ~: W" y. d# [2 [
  163. /*                out                                                                                                                                */! `+ Y8 S0 l: Q& R& `
  164. /*                                                                                                                                                */
    6 g* I% r( c# w) e, Y, v. R. h
  165. /* Output:                                                                                                                                */
    + V- c+ ~$ Q6 t7 ]0 B
  166. /*                SI                                                                                                                                */
    " S1 [2 s5 ^+ A% J9 _6 `7 m/ i
  167. /************************************************************************/
    & t* P9 e' Z/ H1 V7 Z
  168. void Send_Byte(unsigned char out)
    & G. B4 W' A8 i' i* X8 t5 [
  169. {
    5 `2 ^$ U, L+ g9 X' b* Z) b
  170.         " V2 w# U3 o- a6 {
  171.         unsigned char i = 0;: I) l( l0 u& L' ]' ~8 A, S
  172.         for (i = 0; i < 8; i++)
    2 u' x" e! r$ V
  173.         {
    2 A, i2 }$ V  d' N+ p
  174.                 4 x- `0 i; U2 f5 a) _9 O+ R2 d
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */* {" h4 @" T3 t/ W" X2 _
  176.                         SI = 1;- f! E. m$ I2 C1 G2 L
  177.                 else9 \3 u9 @  {2 V! t- B% g+ \" J# V
  178.                         SI = 0;                                /* if not, set to low */
    * M: q) C3 s6 }' _2 ~
  179.                 SCK = 1;                                /* toggle clock high */: t4 M% ]4 z) @, @
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    / }4 G- J- Q9 W8 u& V6 O% z+ n
  181.                 SCK = 0;                                /* toggle clock low */* z( \1 r* \- e: c
  182.         }
    " [( ~( i, V5 K
  183. }# p' z/ K" K7 s7 L! [9 ^
  184.   B: K5 N! D2 N" C0 x
  185. /************************************************************************/
    / z' w9 j6 t, \' D6 u9 m* S  d/ F
  186. /* PROCEDURE: Get_Byte                                                                                                        */2 R' B- R6 v: k$ V) U
  187. /*                                                                                                                                                */
    $ ^* V& G. b+ p  E, e
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    6 ~: c% K$ ?9 Z- l
  189. /* edge on the SO pin(LSB 1st).                                                                                        */6 U: Y: z$ M) c2 o% t
  190. /*                                                                                                                                                */) d1 m+ F7 c" l
  191. /* Input:                                                                                                                                */
    8 Y5 C) I# i. d$ F' ]# c
  192. /*                SO                                                                                                                                */
    " @7 Q  P  Z* Z; B
  193. /*                                                                                                                                                */
    - O1 R" G; `$ t  r" W! ?2 e
  194. /* Output:                                                                                                                                */' p8 y9 X/ h* ?% P5 b, h) L
  195. /*                None                                                                                                                        */$ N$ S" q4 k2 U5 o' {
  196. /************************************************************************/
    9 i" x" A3 V/ f, n( K
  197. unsigned char Get_Byte()2 Q% `' N% m* U3 `5 b; b  C
  198. {
    7 ^! N" i7 h. ~+ y8 D8 U
  199.         unsigned char i = 0, in = 0, temp = 0;
    + i3 I7 w) y: U
  200.         for (i = 0; i < 8; i++)# @+ M: H( e$ R) _3 b
  201.         {
    - k% ^: ~! i' c* k. M+ F4 K
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */; U' F- g" q1 Y/ [
  203.                 temp = SO;                        /* save input */
      |1 n- f2 d0 ^7 p; |2 u+ X
  204.                 SCK = 1;                        /* toggle clock high */+ `" u7 d5 e4 L4 v  w
  205.                 if (temp == 1)                        /* check to see if bit is high */; p; `; S; f# K8 T/ Y' T! u
  206.                         in = in | 0x01;                /* if high, make bit high */( s4 k& W/ `( h) b- r4 k! W

  207. : F2 F1 v: Q  U" V
  208.                 SCK = 0;                        /* toggle clock low */
    0 O+ W! x  D  a# ?: _# U/ X
  209. % [  e  p' \( i" y% j. f* q/ k
  210.         }
    2 m4 ~5 ]" T% B( X1 ?7 c7 n7 {
  211.         return in;
    4 g3 |6 y2 }+ ~3 s- q3 V5 p/ J& ?
  212. }
    / s) ^9 _- T# B/ s# z
  213. , U5 C5 @, `  W) N" y. ?
  214. /************************************************************************/& C8 V1 o, a  E
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    4 ]" ]: ~! N6 Y4 o
  216. /*                                                                                                                                                */2 h/ s; _* M( Q: D' H
  217. /* This procedure polls for the SO line during AAI programming                  */$ B: i) z" f4 r
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    2 V( V5 G. n, `$ A! M/ D. L
  219. /* is completed                                                                                                                        */
    ( j- N" E' c: ?+ ~) W6 a
  220. /*                                                                                                                                                */  K! A! U4 t) Z# s6 W1 }) b/ f1 K
  221. /* Input:                                                                                                                                */8 x/ L+ m" ]0 r$ H* X* X  D  v
  222. /*                SO                                                                                                                                */2 b" D5 D" D! ?1 S
  223. /*                                                                                                                                                */
    ( u& q1 j# J, W* M
  224. /* Output:                                                                                                                                */
    0 \6 F, H8 ]6 N6 O  A8 M. D
  225. /*                None                                                                                                                        */* B, {8 a: S/ P2 a+ v
  226. /************************************************************************/
    $ Q" v( {! B# b% y6 M
  227. void Poll_SO()
    * f# ~0 u8 c6 b7 Y
  228. {1 F$ p9 x- s& g+ ^7 `4 ~* f
  229.         unsigned char temp = 0;
    # W# F  |% S" D2 ^$ z
  230.         CE_Low();
    ( o" a, z# x' d# `$ Y" D5 e
  231.     while (temp == 0x00)        /* waste time until not busy */
    + N  i9 ~5 X; W' n( @
  232.                 temp = SO;  F  b, {4 h/ q( n1 _. M8 e; e
  233.         CE_High();
    % `& z# e0 K6 \! Z2 `
  234. }5 D, f6 g) d! r/ t2 X

  235. . t3 Y! h2 X! U+ y! M% S7 x8 G6 F' a
  236. /************************************************************************/
    ' x; x- _& F5 F; g
  237. /* PROCEDURE: CE_High                                                                                                        */
    & V( s5 Q8 U; l" t3 O
  238. /*                                                                                                                                                */
    ) @6 K7 S& J  e- ?" t
  239. /* This procedure set CE = High.                                                                                */
    4 o: l  m* N2 D0 s3 y
  240. /*                                                                                                                                                */; w2 d3 B: K, K. Z% w
  241. /* Input:                                                                                                                                */
    # L: s% c9 p* z8 W; S
  242. /*                None                                                                                                                        */
    ' {, S/ P4 R8 g3 h8 _
  243. /*                                                                                                                                                */
    * O# x* o) y8 M6 A
  244. /* Output:                                                                                                                                */- w( ~0 C. U- P0 w, k1 c
  245. /*                CE                                                                                                                                */$ ^7 L( O. L3 L2 F7 c1 l# {1 A
  246. /*                                                                                                                                                */& R& C3 |# h; f/ h. w, P* B
  247. /************************************************************************/
    ' G5 e% _- v5 f: x7 E: f, O; o
  248. void CE_High() 2 r6 \  ~, c* c9 d. t* a
  249. {
    9 S5 `: q/ x! E: B
  250.         CE = 1;                                /* set CE high */3 {+ w# o0 ?, z6 }9 i- r$ D: N
  251. }" L9 _6 F4 ~$ e$ R( m

  252. " |& A( |% D2 a! q
  253. /************************************************************************/
    " ]4 q* `* Z3 r4 O3 O$ N+ W3 `& t, p
  254. /* PROCEDURE: CE_Low                                                                                                        */, {+ F' l  }& z( N+ Q! _6 r
  255. /*                                                                                                                                                */+ V- w6 |+ C2 \4 S3 u5 ^9 F+ J6 R
  256. /* This procedure drives the CE of the device to low.                                          */# r5 T8 @5 z" y/ A9 i. f
  257. /*                                                                                                                                                */3 M& Y# [8 |4 C6 u# E  f
  258. /* Input:                                                                                                                                */
    4 X7 ]" p3 h$ b& h0 G, L
  259. /*                None                                                                                                                        */
    ) E! j- T( r7 y* c
  260. /*                                                                                                                                                */+ j% y5 s% f) O& Z
  261. /* Output:                                                                                                                                */' _* R$ f  I8 c. t
  262. /*                CE                                                                                                                                */
    4 B9 P* i9 k3 d2 X% i: O
  263. /*                                                                                                                                                */
    . T3 v% U: J& U1 W; e! M9 r
  264. /************************************************************************/
    * m" x# a9 V# Q$ P
  265. void CE_Low()
    ! r$ w8 j3 v0 b# L1 T
  266. {       
    # P7 l6 W" W  h) ?5 h6 C
  267.         CE = 0;                                /* clear CE low */$ U8 W( r3 K8 i
  268. }, \% F; f4 @( s# U

  269. 5 J& q& N4 D- N6 n. s4 k
  270. /************************************************************************/' k9 {) ~4 }# T! [3 W; u
  271. /* PROCEDURE: Hold()                                                                                                        */: J9 a% U& {- _/ I  x
  272. /*                                                                                                                                                */
    9 M! n, \# p0 Z# P' w- b! D; S
  273. /* This procedure clears the Hold pin to low.                                                        */
    6 [3 j% q- [" }6 `3 E& x5 K
  274. /*                                                                                                                                                */! f) ~& P8 x" e6 }: x
  275. /* Input:                                                                                                                                */
    2 d( i+ @$ B3 a  G8 ]
  276. /*                None                                                                                                                        */
    / `% S& q7 C8 q* u; A) s% X
  277. /*                                                                                                                                                */% d! d2 H8 t9 z+ e1 o3 n, R
  278. /* Output:                                                                                                                                */
    " A. M7 v* U! P0 l: C4 V, d# n+ z
  279. /*                Hold                                                                                                                        */
    , ~8 M* T, L+ T# P- k  G
  280. /************************************************************************/
    4 h5 z1 i9 o& r; n
  281. void Hold_Low()3 N0 s; F% N0 S
  282. {
    2 [/ n5 V3 M; k: I2 |* V' F
  283.         Hold = 0;                        /* clear Hold pin */
    4 q) s$ |: ^2 j! _) ?
  284. }
    ' V2 i$ m+ A. E5 X

  285. 9 W) P3 m; M/ [8 n6 c
  286. /************************************************************************/
    $ r1 q/ p- \3 Z  i9 m2 S
  287. /* PROCEDURE: Unhold()                                                                                                        */  }8 X6 D9 I# ?- c" h0 I" |
  288. /*                                                                                                                                                */0 f* f, N* O1 e3 U& u2 h+ ^
  289. /* This procedure sets the Hold pin to high.                                                        */8 ~' ]( \' Q, T+ |2 ]
  290. /*                                                                                                                                                */
    ; X4 f4 s, g3 f: l3 P" j6 P# H
  291. /* Input:                                                                                                                                */- _3 d8 D- K8 `+ y! b. G
  292. /*                None                                                                                                                        */& R6 r8 e. W3 P: Y: u( z
  293. /*                                                                                                                                                */
    " s: f9 }/ Q$ t2 W4 j+ w
  294. /* Output:                                                                                                                                */
    9 }  m: M; H9 Z1 s
  295. /*                Hold                                                                                                                        */) C/ ~5 j4 \/ i
  296. /************************************************************************/, P$ L4 S* L9 i
  297. void Unhold()
    * T8 i. R2 Z% l5 ?9 }' ?
  298. {! ~5 O$ \2 ?" A& n
  299.         Hold = 1;                        /* set Hold pin */
    8 G3 f* S) ^! \# |: v
  300. }
    & o/ `: S) Q9 t$ h

  301. 1 ~. C! X, f" Z7 @. N! s
  302. /************************************************************************/
      |; X& E* V9 J: k2 B1 V) V
  303. /* PROCEDURE: WP()                                                                                                                */$ h; m' Q4 L* a' m; W5 z
  304. /*                                                                                                                                                */
    4 {5 P" K' e% M, U' h# P
  305. /* This procedure clears the WP pin to low.                                                                */8 h( \* \" N' k
  306. /*                                                                                                                                                */
    ( M2 |1 J9 c3 H% f( t0 Y; Z
  307. /* Input:                                                                                                                                */* u# O& n) `0 T( a( l
  308. /*                None                                                                                                                        */7 [2 O* m. H3 g1 f
  309. /*                                                                                                                                                */: [; Q" p$ U8 \: F
  310. /* Output:                                                                                                                                */
    % @, {3 e; Y0 d- I% u& i. j
  311. /*                WP                                                                                                                                */
    1 v9 z* t- h1 U6 m( y; c
  312. /************************************************************************/+ s' z- v, `7 ^9 F
  313. void WP_Low()% L% l$ |# E/ D2 Y0 |: @2 `9 v
  314. {3 p# K& z  n0 B  ]7 U' J; M( O
  315.         WP = 0;                                /* clear WP pin */$ S# o; f7 q" A  c* |! A: A5 ^1 e% M, S
  316. }
    - p$ }9 R- s& e4 w; i* Z9 t4 J2 t
  317. / W& F" h1 L3 j. f! s- |0 Z
  318. /************************************************************************/
    0 F8 d8 W' b/ t
  319. /* PROCEDURE: UnWP()                                                                                                        */9 Y  h' j. V0 `/ _/ P  R
  320. /*                                                                                                                                                */4 ?9 h! ]2 I  F3 V$ ]' u
  321. /* This procedure sets the WP pin to high.                                                                */
    ! `4 p5 o& c6 d
  322. /*                                                                                                                                                */
    & _! p* N& R6 q
  323. /* Input:                                                                                                                                */
    0 D9 V$ S! \, u: Z
  324. /*                None                                                                                                                        */8 \$ T: l4 ?% g1 P; W/ Y
  325. /*                                                                                                                                                */
    / [. u$ X. j8 p
  326. /* Output:                                                                                                                                */6 o1 l9 B9 L$ X+ q! T$ g
  327. /*                WP                                                                                                                                */- r. N- D2 L1 n2 j, p2 V0 f  D
  328. /************************************************************************/$ i; @7 }. ^$ U" X0 U
  329. void UnWP()
    " I" s! o7 C5 F
  330. {
    $ T, c) b5 z  l  Z4 O0 p! w4 O
  331.         WP = 1;                                /* set WP pin */3 k4 M+ k! @; c* l  |" x( o
  332. }
    4 y0 W( s/ q8 B7 R

  333. , d( H" h* `$ R: l5 T
  334. /************************************************************************/
    6 N* I) @  X+ L
  335. /* PROCEDURE: Read_Status_Register                                                                                */& p, i* f* v4 B
  336. /*                                                                                                                                                */
    : r, x2 K+ f; n9 i
  337. /* This procedure read the status register and returns the byte.                */$ D0 ^0 E) U/ ^7 l) _
  338. /*                                                                                                                                                */
    + G5 \6 ]% F7 P" R% h# Z/ y
  339. /* Input:                                                                                                                                */+ F. x  U7 a8 {( Q
  340. /*                None                                                                                                                        */
    6 d% }' I9 R9 ~6 v0 _
  341. /*                                                                                                                                                */
    ) {5 I$ N. G& g2 a& a, _- p2 d' T; H
  342. /* Returns:                                                                                                                                */
    1 n- B) c/ L, F* O
  343. /*                byte                                                                                                                        */3 T7 T  ]# |  o
  344. /************************************************************************/
    ( U6 `/ b3 Y; J& m8 e- w
  345. unsigned char Read_Status_Register()3 E7 S2 H5 [2 \' n# ]+ b( A
  346. {. w, v0 L0 A' S6 H8 i5 l9 S6 I
  347.         unsigned char byte = 0;
    % z2 n1 [9 F8 y7 t' ]+ h8 a
  348.         CE_Low();                                /* enable device */
    : \: T4 k  g' T' _9 `
  349.         Send_Byte(0x05);                /* send RDSR command */# C3 W& T& Y& P7 f" k* B  _3 b
  350.         byte = Get_Byte();                /* receive byte */- K/ @# h1 V! r6 Z% W
  351.         CE_High();                                /* disable device */
    ( R6 ~: ]0 W: a( ~: M6 E
  352.         return byte;6 V* X" B5 R8 L% E. i
  353. }
    4 ]% M* J' M' k0 T: h! C$ F

  354. 5 ]3 j* }9 R" C. Q6 |
  355. /************************************************************************// P7 g: C1 s( }$ [( g
  356. /* PROCEDURE: EWSR                                                                                                                */- F- S( Z* ^7 R1 \& L( ^9 o. t
  357. /*                                                                                                                                                */
    . A  J% K9 j# M, V! z
  358. /* This procedure Enables Write Status Register.                                                  */  }- |* o6 o3 r3 L' |& w9 G
  359. /*                                                                                                                                                */0 u6 A) C$ W( W; g7 v
  360. /* Input:                                                                                                                                */
    0 }' j1 Y2 v2 m& _) A' H
  361. /*                None                                                                                                                        */2 Z8 u& W) W# O' C( p
  362. /*                                                                                                                                                */
    4 K# y; [  K; k* |5 z
  363. /* Returns:                                                                                                                                */7 b& N9 }. W. x2 u: _1 b
  364. /*                Nothing                                                                                                                        */+ g: T; G( E% a, H* q  M
  365. /************************************************************************/
    $ Q% J" y( q0 |; x( P
  366. void EWSR()" O" D$ G' s% b5 J6 I: Z0 Z: h# S
  367. {
    ; x- P% ~, k- |% F8 j! @  J/ z
  368.         CE_Low();                                /* enable device */
    + o2 [' i. J) R  w$ g) R1 F
  369.         Send_Byte(0x50);                /* enable writing to the status register */6 ]7 n- \. F* b0 y8 H( O
  370.         CE_High();                                /* disable device */
    & b+ I& H! y, Y: Q5 E& u9 P7 U
  371. }% m" ?( D  r' |

  372. 3 Z/ D- g: g% w8 c6 I# D
  373. /************************************************************************/& l; }( w: C  [4 s
  374. /* PROCEDURE: WRSR                                                                                                                */& _0 f; M- k  d# K
  375. /*                                                                                                                                                */
    2 D* G8 K& w: \/ Y
  376. /* This procedure writes a byte to the Status Register.                                        */3 @. \! d" d9 v1 j) m2 Q, Y
  377. /*                                                                                                                                                */# ^  I$ o7 o+ {# l5 z
  378. /* Input:                                                                                                                                */
    * S" Y4 c/ u  n: @/ e% z+ ?( `
  379. /*                byte                                                                                                                        */! e, Y; {6 b% l6 n
  380. /*                                                                                                                                                */& G3 }9 O3 U0 `
  381. /* Returns:                                                                                                                                */
    6 h7 E; R! j( s; j& e: }, q: z
  382. /*                Nothing                                                                                                                        */
    2 y. I/ c3 O6 V9 h
  383. /************************************************************************/
    & s6 S" e+ L) K
  384. void WRSR(byte)6 Z* D- ^: F' p9 Y4 ]" l, \
  385. {
    8 ~& o  ?# t  ?6 a5 j9 H! }
  386.         CE_Low();                                /* enable device */
    " I$ @- j0 d9 u7 w0 K+ Z0 U
  387.         Send_Byte(0x01);                /* select write to status register */% l" y6 |4 M: C5 o
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    ) k2 ~: @. V  j0 i' Y, D3 W
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */( b- g9 K  j5 i5 N1 W
  390.         CE_High();                                /* disable the device */9 S9 q& u- o" U9 e
  391. }4 V2 _" m7 u- H

  392. & F0 K3 G8 v; a
  393. /************************************************************************/
    # D, _5 {; e" [6 [4 u4 t
  394. /* PROCEDURE: WREN                                                                                                                */& _! |: p) `" V! G
  395. /*                                                                                                                                                */
    ( y* g" k3 g; C  ^0 u
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    ' y8 Y4 d/ r1 i
  397. /* to Enables Write Status Register.                                                                        */2 g( c. A( i" H. w% U) _$ l
  398. /*                                                                                                                                                */6 O* o; L$ J9 a6 X
  399. /* Input:                                                                                                                                */" f5 B& r7 _, t0 Q: w
  400. /*                None                                                                                                                        */# @+ Q1 o! |! O" \' e
  401. /*                                                                                                                                                */
    # K. P8 g& }0 b4 `
  402. /* Returns:                                                                                                                                */
    / L" q1 d1 T, p' ]
  403. /*                Nothing                                                                                                                        */4 e- m5 `7 x$ K$ x2 k; N" P
  404. /************************************************************************/4 o+ D9 `; e* U( s( B8 q
  405. void WREN()
    / H0 i1 R' d6 e' F# d3 s
  406. {+ \8 {; k: ?7 a' g
  407.         CE_Low();                                /* enable device */- E0 }9 B4 u' v# g. g2 I
  408.         Send_Byte(0x06);                /* send WREN command */
    * P% J0 u! X2 S  d1 s
  409.         CE_High();                                /* disable device */
    ) O2 {0 ~, {% z2 o
  410. }
    * V2 M; p2 S3 M  n+ h( J
  411. - H$ S; h" Q5 E& N& M
  412. /************************************************************************/
    8 ^% y8 u0 V" z3 N; |8 j, ^
  413. /* PROCEDURE: WRDI                                                                                                                */
    3 ]" ]+ B2 ~+ M; y
  414. /*                                                                                                                                                */1 U$ u9 T0 k/ D0 e# g3 s) g" F
  415. /* This procedure disables the Write Enable Latch.                                                */
    " `/ y+ w7 W; G1 `" o6 `& E
  416. /*                                                                                                                                                *// |( T1 K+ P8 u7 B9 b4 d
  417. /* Input:                                                                                                                                */
    3 V4 ~, K9 {* u  T8 w) U2 Z
  418. /*                None                                                                                                                        */# X3 h, p; D  S7 A8 A% G
  419. /*                                                                                                                                                */
    " U- k$ e( g' w3 O$ q1 G: E3 g7 D
  420. /* Returns:                                                                                                                                */0 Y( P1 O  M0 Z# P$ X
  421. /*                Nothing                                                                                                                        */
    ) \& G% q* y/ n3 I8 ]5 E8 j
  422. /************************************************************************/
    ! Y4 y9 [' }! Y1 W$ i; O
  423. void WRDI()3 e4 P2 V: s1 Y
  424. {# {! C% g) a9 M4 c0 a
  425.         CE_Low();                                /* enable device */
    : G, B0 X/ T* N4 v  X  r- _. M6 u
  426.         Send_Byte(0x04);                /* send WRDI command */9 }' e/ F- F0 a6 S
  427.         CE_High();                                /* disable device */
    , A, F# c1 _3 u/ `( ?6 h7 t: [
  428. }
    3 e) ]( r% W- F9 P

  429. 6 H9 ~( `  b5 f+ [- O! S8 U
  430. /************************************************************************/) e" Z' g. y! k0 _
  431. /* PROCEDURE: EBSY                                                                                                                */
    : O! N! B  |  j9 V" \, J8 T# g
  432. /*                                                                                                                                                */
    9 z# x8 f% O# K) D+ C
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    * ?/ J4 W' l3 f) }/ w# q$ B
  434. /* programming.                                                                                                                        */* N7 `8 @+ B3 P* y# f# S
  435. /*                                                                                                                                                */, u9 g- a- d  b8 ?: {; w
  436. /* Input:                                                                                                                                */3 h6 b3 P$ G! H) o
  437. /*                None                                                                                                                        */9 k- _* G% i0 |$ o% e8 V
  438. /*                                                                                                                                                */
    7 ]- x6 U2 c9 C0 W
  439. /* Returns:                                                                                                                                */! S& M# N7 b2 y: l! v! Y
  440. /*                Nothing                                                                                                                        */- e" m8 v4 y6 y
  441. /************************************************************************// @# L( u% c2 z. G$ `* p2 w
  442. void EBSY()* J4 M+ _* H1 ^4 O6 _' _1 X) J
  443. {6 X3 g) k$ z$ J1 ~+ G  D
  444.         CE_Low();                                /* enable device */
    , E, O- X$ f$ `8 V/ F
  445.         Send_Byte(0x70);                /* send EBSY command */
    ( V: [" `& Z7 g5 W- m5 s
  446.         CE_High();                                /* disable device */
    6 f- y9 m! F/ H+ B/ d
  447. }
    2 B1 ^9 j# a) \4 s7 k2 k9 i

  448. $ k) l$ |" Y3 p( R$ K7 g2 P$ w. G
  449. /************************************************************************/, S! i7 U: ]4 o5 I/ P
  450. /* PROCEDURE: DBSY                                                                                                                */
    3 w9 d% t) E* U  H
  451. /*                                                                                                                                                */
    $ ~3 ]4 b4 C# h6 c7 L& b
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */0 C6 l0 ~1 h1 u2 m( M: j3 ^0 Y
  453. /* programming.                                                                                                                        */
    0 I- Q$ t1 W$ _# M2 W8 C  W
  454. /*                                                                                                                                                */5 ~! F# X2 _1 }: V8 u
  455. /* Input:                                                                                                                                */! ^. s9 c5 H; @& Z
  456. /*                None                                                                                                                        */* U$ z: g( i# E0 V1 b9 `7 ^  L" ~
  457. /*                                                                                                                                                */
    ) ^! Z+ n9 Q# g. k- _3 S2 K  f
  458. /* Returns:                                                                                                                                */
    * p) o1 s7 z. b0 q- R  B6 l! d) I
  459. /*                Nothing                                                                                                                        */* T+ ?8 w) D9 X
  460. /************************************************************************/8 k: B+ J0 \  Z0 Z8 G! F
  461. void DBSY()) d1 w( d  J  {# @
  462. {
    4 G! h. G+ V& G, l, |+ j" h8 Z
  463.         CE_Low();                                /* enable device */
    / F6 m+ y. h7 i7 d8 u
  464.         Send_Byte(0x80);                /* send DBSY command */8 q0 Q$ [3 L$ C/ e, d0 s* U( y3 W
  465.         CE_High();                                /* disable device */+ F. A* f* F- [9 k$ y" ~6 X0 ?. i
  466. }
    % a' |. [! L7 H

  467. - [/ q  i! A# X3 t
  468. /************************************************************************/
    7 ?1 e1 P0 j' C0 B
  469. /* PROCEDURE: Read_ID                                                                                                        */3 m7 I' I4 V7 j% c
  470. /*                                                                                                                                                */  W: \% U0 z. m3 K* u4 a
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */4 Y: c4 d8 T1 V, W+ M
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */6 {7 B. F- q/ N* I
  473. /* It is up to the user to give the last byte ID_addr to determine      */
      A( M' O# C+ F
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    9 H1 y" ~) |; `* t6 z
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    ( R$ |- q4 z6 ?, k* ~. h! F! }$ ^
  476. /* variable byte.                                                                                                                */6 c4 Q6 i7 `3 \" N; C$ J
  477. /*                                                                                                                                                */
    ' ]$ \8 h! E8 E; I3 i
  478. /* Input:                                                                                                                                *// d+ |6 E  q; s  I6 @" U
  479. /*                ID_addr                                                                                                                        */: j: R" C4 |  j6 t. S- v; Q- m
  480. /*                                                                                                                                                */$ c3 c7 v/ `" p- ~8 [
  481. /* Returns:                                                                                                                                */1 z4 a' t1 n# Z+ j, O
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */& X+ U. X: b, }
  483. /*                                                                                                                                                */
    : p4 n/ r+ ?+ c' V4 x
  484. /************************************************************************/9 X* z# }& C/ u
  485. unsigned char Read_ID(ID_addr)
    ' ?; B0 l3 a* ?0 m
  486. {/ y4 a/ T4 G8 a
  487.         unsigned char byte;0 ?5 R8 ~2 K1 N  y5 o: [
  488.         CE_Low();                                /* enable device */
    / Q8 Z& U% d/ k% R) W7 i
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */) x0 ?# o0 [2 k/ k2 @- `# ^% E
  490.     Send_Byte(0x00);                /* send address */% H) `$ `) K, @' H: X: a1 R
  491.         Send_Byte(0x00);                /* send address */- n% |2 x, Y+ i. Z7 A; o9 R
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */; U. a0 u6 m( ?4 s1 b6 M' q
  493.         byte = Get_Byte();                /* receive byte */+ o" x0 d) H# b1 S5 P) s8 G
  494.         CE_High();                                /* disable device */
    1 Q  A) t& x) f. a: s* x
  495.         return byte;$ m2 ]  Y# a8 ^$ Z( s5 s
  496. }' B, ~- O2 X# ^/ w4 h

  497. % k+ F" k% W( z+ `  O8 C; B
  498. /************************************************************************/- e. A# t2 S9 ]' ?
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */1 M, m' @6 E6 S2 ]7 H
  500. /*                                                                                                                                                */
    3 ^; S6 Q+ ^& ^0 w% H' _
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    ' B  s( B8 o0 c6 e: h( J; f: f5 T
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */# R6 q2 u, I: C# ~' `3 w: ~- i- u
  503. /* Please see the product datasheet for details.                                                  */, J# s: j; H+ z0 S/ z8 Z* B5 p* ^) j
  504. /*                                                                                                                                                */
    , s1 R1 @9 h& ]% u# U% c
  505. /* Input:                                                                                                                                */
    ' O0 @, h; }0 N/ x! d& M6 Z" `
  506. /*                None                                                                                                                        */
    : N- V7 h" i0 u- Y/ ]8 ?
  507. /*                                                                                                                                                */
    $ r- d, P: W, h, H0 G
  508. /* Returns:                                                                                                                                */0 x% X7 s# _  t8 I$ P4 ]% P
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */$ W3 h: j; L: c7 Y4 _7 l8 l( m6 d
  510. /*                 and Device ID (8Eh)                                                                                        */& v; E  V; ^" V1 W8 d+ }
  511. /*                                                                                                                                                */
    . ?8 H7 x, x* k! U8 K" c  H9 Z$ V
  512. /************************************************************************/: G  _: _( t+ z: I$ g
  513. unsigned long Jedec_ID_Read() ; I$ O# M- w3 k) h
  514. {
    ' m: R5 Z' b! w- j+ T1 ~9 |
  515.         unsigned long temp;
    0 l) {! @3 [; \1 y
  516.        
    + O9 ~9 [5 v( r/ }; o3 h
  517.         temp = 0;/ H: A- b% Y  J' Q* K
  518. , q* V0 A. x) P
  519.         CE_Low();                                        /* enable device */* V* Y8 _# u/ u# m% {9 v
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */6 T* Y( d7 Q9 k- n* y) k0 k; z1 [
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    % h. S6 q8 @, w- u4 g7 {5 M
  522.         temp = (temp | Get_Byte()) << 8;        + ~2 ?9 Q4 _% m/ i/ Q: I, E6 ]! C. z
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */1 L% ^: Q; r6 B& S+ h) [! z
  524.         CE_High();                                                        /* disable device */
    5 S" i5 @0 }7 h

  525. 0 }3 O1 N% b# M* v( `4 p
  526.         return temp;! t' W/ K( l7 g8 n, n) O- @1 j/ s
  527. }
    ! t9 {; j: |- L0 E% N# G6 m6 }* ^) t

  528. 7 h8 P/ b+ h4 F8 U$ D
  529. /************************************************************************/! m( n- \( G1 `' L3 b
  530. /* PROCEDURE:        Read                                                                                                        */; s+ ]+ }0 d# ~) X' t1 X2 E
  531. /*                                                                                                                                                */                  L/ j9 \8 |* t6 O: q
  532. /* This procedure reads one address of the device.  It will return the         */
    # q1 v* y- w# ]4 S8 ~7 T
  533. /* byte read in variable byte.                                                                                        */, g9 c1 c1 B: O  U  O  n
  534. /*                                                                                                                                                */
    , U+ Q4 V7 [1 ^! n- y
  535. /*                                                                                                                                                */
    3 G2 q1 O2 p: N1 D4 W
  536. /*                                                                                                                                                */
    5 s+ v8 M$ a1 h; G; S% f
  537. /* Input:                                                                                                                                */
    % p- L6 n0 Y! R7 R% M. _* K2 C' d
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    % w; W/ M. V0 z9 P& L8 y& y
  539. /*                                                                                                                                      */
    * J+ A8 o+ b6 s( U' C7 ~
  540. /*                                                                                                                                                */3 B% x1 q( }1 k. G, g, b5 _
  541. /* Returns:                                                                                                                                */: }1 m0 T/ [% q' J8 C% C
  542. /*                byte                                                                                                                        *// V6 {, [! Y- g: P  t
  543. /*                                                                                                                                                *// W2 ?  P( I* H' Y- R5 v" Y  j
  544. /************************************************************************/
    * o8 P: h. Z7 V- e, R
  545. unsigned char Read(unsigned long Dst)
    : m5 G5 X5 d& t
  546. {6 a' q0 ~2 R9 W/ ]: R
  547.         unsigned char byte = 0;       
    & }0 F$ b3 l4 [- O8 @; v* v
  548. ! P' a( c* B1 R6 I6 x1 t5 m
  549.         CE_Low();                                /* enable device */9 H/ v& q/ O% ~9 }4 [& R/ Y
  550.         Send_Byte(0x03);                 /* read command */
    " H8 q1 _' p  R5 ?
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */, b9 M7 o" ~8 V- I% G# `: X+ X
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));3 t( r- m; T' v, k7 W2 s
  553.         Send_Byte(Dst & 0xFF);
    : n0 H: B3 u! V, t
  554.         byte = Get_Byte();- ?+ d3 g5 A1 Z; Y1 t$ f
  555.         CE_High();                                /* disable device */
    : ^: U, _4 S% z1 B7 F% W# Q' h
  556.         return byte;                        /* return one byte read */
    , g* l1 t# @4 P
  557. }
    2 Z: O0 B3 L/ q0 d2 T, ?5 J
  558. 0 f9 d/ u7 a* x1 X7 P/ |* M
  559. /************************************************************************/
    % y% k# R3 p  X( D' w* j
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    3 ]: Z# P* w6 r/ u( ~
  561. /*                                                                                                                                                */               
    & F7 h* s4 \" i6 W/ p
  562. /* This procedure reads multiple addresses of the device and stores                */+ [! ~8 p4 ^( O) x1 G" I
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/: N5 I+ D5 M: |- y" C, K4 c
  564. /*                                                                                                                                                */9 f8 |% n/ _" E8 I4 W! U1 ]
  565. /* Input:                                                                                                                                */
    & P! Z7 r8 p2 E9 L) x" k3 M9 h! ~
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    $ O1 E9 W/ E" w- p
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    % D1 {* i; T+ r5 L
  568. /*                                                                                                                                                */
    # [: r, X" v8 v3 B2 z2 p7 L
  569. /* Returns:                                                                                                                                */+ U" D+ B' k3 y) c
  570. /*                Nothing                                                                                                                        */- D# s; t# |6 b2 b* C0 }# D1 F( |
  571. /*                                                                                                                                                */
    8 `4 A9 I# f9 Z7 w
  572. /************************************************************************/8 E. s& _& E% {  u, k- l
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    $ r1 [+ s- T8 \7 D* J: k
  574. {
    . a3 f  b7 ~# H; n" E
  575.         unsigned long i = 0;" r3 f8 t2 ?. I+ H0 |4 `5 h( r$ _$ ^+ q
  576.         CE_Low();                                        /* enable device */- f+ \- R5 X) R
  577.         Send_Byte(0x03);                         /* read command */
    3 h9 g" X/ v6 \+ x  p
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    & w$ x( c: o: G  E- B+ l2 \
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
      ?( G3 Q: Z' _
  580.         Send_Byte(Dst & 0xFF);
    & Z9 u- _; k' v  F. v& v
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    : Y3 h, @+ y; x- r  V0 @
  582.         {
    ; G( V1 A. S  `% I6 `8 p( Q
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    & Y' _; S( `+ V% x: ^2 l) G
  584.         }
    & F& i9 G$ T# i! F  k1 E% S5 K# M
  585.         CE_High();                                        /* disable device */
    $ ]% b, i8 g( l; H" h( A
  586. ! X% \+ M( [. B" l8 p) G% k
  587. }" ^. j; H  V+ j2 `) u

  588. + Y) `8 O/ L5 t) c0 q' }
  589. /************************************************************************/
    , a2 e( p4 T' u
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */- c% u. z& [3 o) X
  591. /*                                                                                                                                                */                - J' h# m' O1 @3 ]$ F6 ^: s( X' q
  592. /* This procedure reads one address of the device.  It will return the         */3 \! ~  Z# S2 L
  593. /* byte read in variable byte.                                                                                        */
    % B/ @0 |% J& s) |4 @) C
  594. /*                                                                                                                                                */. C, V0 Q# V; e
  595. /*                                                                                                                                                */
    / D/ Z, F& q! t0 X4 i; w
  596. /*                                                                                                                                                */
    - J8 U' C( Y2 M6 Y$ |+ F
  597. /* Input:                                                                                                                                */. ]8 v! J3 C6 A, f/ \" e
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    ) M7 `( q$ v: K- j
  599. /*                                                                                                                                      */5 m. ]) F- S7 O* t0 r! H: j+ M, P
  600. /*                                                                                                                                                */
    - z8 h( `# ]$ L( ]2 ]" o; a
  601. /* Returns:                                                                                                                                */. J; Z+ s0 K4 ]
  602. /*                byte                                                                                                                        */
    ; x2 Z( }1 V1 U  N
  603. /*                                                                                                                                                */* ?7 h' ~6 ]  }) j2 L% D/ O$ X+ G
  604. /************************************************************************/+ _* X( ^, E; V
  605. unsigned char HighSpeed_Read(unsigned long Dst) - r( q' J$ E" Q, i" c8 P: f
  606. {6 ?3 T5 O( w: n( K
  607.         unsigned char byte = 0;        1 k- R8 i/ V& N- q2 I  x' y

  608. 1 R. X+ F5 ^3 C  F
  609.         CE_Low();                                /* enable device */$ w$ j" y& ?* b3 @# b
  610.         Send_Byte(0x0B);                 /* read command */* D- |1 `- w6 a1 a7 `5 {& m. g. ?; Y8 h/ [
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */3 n- \( E9 d" Q( s% u' H
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    # r5 L% W0 {% G+ k9 y
  613.         Send_Byte(Dst & 0xFF);5 @' g  l! s% ]; b
  614.         Send_Byte(0xFF);                /*dummy byte*/
    & T9 w2 {, Z0 ~' W
  615.         byte = Get_Byte();! v' h* s3 e, d* v% V! h! q
  616.         CE_High();                                /* disable device */& ?+ M  h) |0 }9 j' s* h
  617.         return byte;                        /* return one byte read */, a) m* `0 E9 q0 X& y3 {2 y9 f
  618. }
    ) |' J8 U( h) ?, e) T3 D
  619. & i* n/ k0 \8 f0 a4 j
  620. /************************************************************************/9 i4 ~9 P: i. V# [
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */5 t/ O% F) E1 c* |8 h. p7 v# ?) }
  622. /*                                                                                                                                                */                . X% B$ L" M  w! H6 c4 t& C$ s
  623. /* This procedure reads multiple addresses of the device and stores                */
    . a4 [% K% E/ q5 r- \
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    + Z4 r2 @! J7 [; x
  625. /*                                                                                                                                                */
    & S$ n2 x% l4 D1 r
  626. /* Input:                                                                                                                                */4 m- w. b& R0 l- n
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */4 k( p/ |* J; \) D9 a
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    7 y1 E! f# x+ |/ S  k
  629. /*                                                                                                                                                */
    / `! D8 o6 H" R& \
  630. /* Returns:                                                                                                                                */* N) ^0 t; H. Z3 o
  631. /*                Nothing                                                                                                                        */+ h; a( X! l' M9 h' ?0 y) n% y
  632. /*                                                                                                                                                */
    ; m2 s$ J1 e& Y& W
  633. /************************************************************************/
    $ @. {, L& p( y- H7 y+ e
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    & o# S/ b% C7 x+ @& b! L
  635. {( [2 `' t3 g+ y3 @) b
  636.         unsigned long i = 0;3 S+ j2 a4 @/ D5 q( w7 X
  637.         CE_Low();                                        /* enable device */( U3 u& o6 p; c, k. F2 K# {
  638.         Send_Byte(0x0B);                         /* read command */+ H5 X( t$ W$ Z0 g  ^& V% E9 m+ {
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    : U. j7 O/ N; V8 j$ [, b3 O: {
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));  U6 J0 R' a2 w- |
  641.         Send_Byte(Dst & 0xFF);$ G/ I+ z6 o+ a6 i" [
  642.         Send_Byte(0xFF);                        /*dummy byte*/. c* o. _% b) _5 J: \
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    $ Z- B/ v3 s; C
  644.         {8 g/ h1 k2 A* ]4 V
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    1 ^! E" _, O. r+ v
  646.         }
    2 U3 B6 j' h/ D/ _. d  U, Q* `
  647.         CE_High();                                /* disable device */2 |3 ~& {0 D& [/ s" B
  648. }5 Q" O$ V6 ~& s& y" O" t' K

  649. 5 `' t$ |6 ]6 U7 w8 @- ~
  650. /************************************************************************/# J0 D* G0 l" z6 V
  651. /* PROCEDURE:        Byte_Program                                                                                        */$ f; d, {3 ~  q7 y  r
  652. /*                                                                                                                                                */
    ' G- Y, G% x. T' d6 f. z. |. @! |
  653. /* This procedure programs one address of the device.                                        */+ c& W. e( J  g; o
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    9 n7 I# y$ o" F6 }! S# M, t6 i
  655. /* block protected.                                                                                                                */
    1 w! D- |/ {/ R9 R" n
  656. /*                                                                                                                                                */$ A9 o) C0 H; z0 o+ E% y
  657. /*                                                                                                                                                */
    $ _. e+ {" w6 y2 x6 q& S7 ?
  658. /*                                                                                                                                                */
    # e. W: P- N  u9 g. z5 ~
  659. /* Input:                                                                                                                                */
    6 f1 c8 }; ~( w% `
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    , y1 E, G- _5 U1 [) @1 F4 I  J( m
  661. /*                byte:                byte to be programmed                                                                */
    6 @: b, q# d' X/ U4 T
  662. /*                                                                                                                                      */% r+ f0 R9 r5 O/ i- k, m) J
  663. /*                                                                                                                                                */
    2 l1 N- M0 F. y0 S) {& r
  664. /* Returns:                                                                                                                                */
    * I/ k2 [$ r9 I
  665. /*                Nothing                                                                                                                        */. N/ g5 I5 w  w1 S1 x% E
  666. /*                                                                                                                                                */
    / g; T. a) @. {9 E) Q% f
  667. /************************************************************************/. e, d0 C+ F" N3 O: p
  668. void Byte_Program(unsigned long Dst, unsigned char byte)& _+ O: @" N( H5 w9 ]$ x" C% M
  669. {
    ' W6 z2 c& P3 D; I" I2 x
  670.         CE_Low();                                        /* enable device */
    9 u) w3 l/ Z9 {# L& ^
  671.         Send_Byte(0x02);                         /* send Byte Program command */' t& }% ?$ ?7 h4 G
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */! L4 }7 h" N$ v5 r4 y
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " ^: Q7 r1 ]+ q# r2 G5 z
  674.         Send_Byte(Dst & 0xFF);
    + T" |  J0 u8 c9 ?% T- X
  675.         Send_Byte(byte);                        /* send byte to be programmed */, F2 Z1 N# d( V: y8 k$ ]3 ]
  676.         CE_High();                                        /* disable device */& V# n+ L6 n* d0 j6 {5 E
  677. }" U0 I( @$ f6 t% |& g% v) u; P
  678. ; m5 K: J( Q2 N+ o
  679. /************************************************************************/
    , ?( |. p7 n' {% {8 W4 Z5 v
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */+ h# h5 K, Q7 f) F1 p! h
  681. /*                                                                                                                                                */
    3 O4 s- W6 z' g% G: s! d: H6 I8 T
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/0 g- m; L- v7 J$ x
  683. /* the device:  1st data byte will be programmed into the initial                 */
    5 ?1 p3 k4 C. i. P6 \) E) }% }  T1 H
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    ( x! ^1 E9 Q" A+ C! B
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    . w9 A* j2 f5 S; W
  686. /* is used to to start the AAI process.  It should be followed by                 */
    $ F% t5 t$ i* h8 T$ i
  687. /* Auto_Add_IncB.                                                                                                                */; t) p; x1 _% h$ Q. p1 u
  688. /* Assumption:  Address being programmed is already erased and is NOT        */7 z+ J6 E; J9 _- u( k! Z
  689. /*                                block protected.                                                                                */) Q% z1 s7 G8 d5 w- z) y" j, R
  690. /*                                                                                                                                                */; F' t/ I" q) G! O) E
  691. /*                                                                                                                                                */
    6 a% `. e0 v3 k
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    : |& A( U* ~( F+ ?; Z: d
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    ' T6 Z+ {8 C3 x  [
  694. /*         unless AAI is programming the last address or last address of                */' Q) [8 \  E' e9 g
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    % Q8 Y, [* x9 E( N7 C+ n
  696. /*                                                                                                                                                */9 H; t/ D: w* Z% N+ U9 Y5 E# g
  697. /* Input:                                                                                                                                */. C& C& m) Z  j5 f5 f9 n
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : v1 s6 W; U+ q4 I" k" H" N
  699. /*                byte1:                1st byte to be programmed                                                        */
    % c4 w6 B1 n+ a$ o
  700. /*      byte1:                2nd byte to be programmed                                                        */% _# F/ [* C5 w# V3 t2 w
  701. /*                                                                                                                                                */
    ; B# `  M: z# V' B/ V
  702. /* Returns:                                                                                                                                */
    - N$ z1 Q& D0 _8 }/ \3 c* |
  703. /*                Nothing                                                                                                                        */
    3 h6 t& t9 Z& A% w0 i- k
  704. /*                                                                                                                                                */; K4 ~7 R" X, i/ o% @$ U" [: R% m1 U
  705. /************************************************************************/
    ) T! U7 i; |& t8 e( o
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    , o; H. X% O- D2 H/ ^. h
  707. {3 Z' {  y- V8 E6 F
  708.         CE_Low();                                        /* enable device */
    ( a; F. y; z* R6 |* B& `0 ^5 h
  709.         Send_Byte(0xAD);                        /* send AAI command */
      H* D0 H' i0 N* ?4 h) P% _" l  T
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    8 O. n& i. q5 a4 b- _3 V! R
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
      E/ Y0 x1 U& w! `  g
  712.         Send_Byte(Dst & 0xFF);3 _7 m; C6 l7 M  Y1 F
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        * T- Z9 q  Q: d$ i) _( i
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    : E# a; ^/ K5 v3 u
  715.         CE_High();                                        /* disable device */
    - P  l' E! b2 v% Y  P4 u2 d1 E
  716. }5 U* D7 `# B" ~" \  H: l

  717. ' |8 Y3 e" T  D* x) w! x1 @3 {3 R5 J
  718. /************************************************************************/# Y$ x9 c: z. y. b6 M9 d; Y5 f# @
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */) i9 ~2 I% K: N. O% E# n
  720. /*                                                                                                                                                */: ~' `% i$ |- D3 ~9 ]/ }: o
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/( h0 S: m# {0 P7 }* g5 ~( M  z
  722. /* the device:  1st data byte will be programmed into the initial                 */
    ( q+ n" G9 h: e+ M( p
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    . w) p4 a% `" `2 j, u- Y2 u- i. Y
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    , L) o& o6 N: {' u1 R' V5 i9 X5 v
  725. /* is used after Auto_Address_IncA.                                                                                */5 q4 w& M3 a2 x! s$ T6 O9 F
  726. /* Assumption:  Address being programmed is already erased and is NOT        */5 ^/ C% f. b& {; h5 w4 a% i) k) V
  727. /*                                block protected.                                                                                */) T! [+ p! V* U" ]" t/ g" l' J
  728. /*                                                                                                                                                */9 p5 e$ [. V+ S0 e5 O3 X/ C7 r
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    5 Z3 t% G' Z% ~5 `# {& ~6 s: _8 k
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    5 v7 \. |- S0 b; r
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    4 d, D4 D. C: F7 K) M
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    ) ^* j/ a" E% D' y8 ?/ X
  733. /*         last address of unprotected block, which automatically exits                 */4 H) A7 A! M2 I5 P) Z( v9 N8 \) t! J
  734. /*         AAI mode.                                                                                                                        */, \" C' z4 y- y3 V; d7 |& u2 x1 v  c
  735. /*                                                                                                                                                */5 n& I1 n9 [% n( F
  736. /* Input:                                                                                                                                */* |, J- R, N3 `( o" a
  737. /*                                                                                                                                                */$ n; |/ y9 G/ \3 ~
  738. /*                byte1:                1st byte to be programmed                                                        */4 t, T0 Z' X, S) U4 K* ?4 o
  739. /*                byte2:                2nd byte to be programmed                                                        */
    / q, C/ M& h! w9 p" K9 C
  740. /*                                                                                                                                      */
    6 x% `) n1 y. {1 _0 ~/ w( M6 C
  741. /*                                                                                                                                                */3 u, H! K  _) O4 V/ o5 c
  742. /* Returns:                                                                                                                                */& x& q- V+ m. X5 t, v) c
  743. /*                Nothing                                                                                                                        */6 e7 |' g  A* a% H
  744. /*                                                                                                                                                */& x8 E- j- C- _5 c
  745. /************************************************************************/
    0 k& t8 q, x. A5 T
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)4 ^9 G) M* ]4 E. @! S
  747. {/ L" q( Y' i4 E* ]/ ^( `, f
  748.         CE_Low();                                        /* enable device */4 I2 k; ^3 D2 A& ^5 [& m7 r
  749.         Send_Byte(0xAD);                        /* send AAI command */) V/ g* C2 F6 V5 \& p( B
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    ) N% \+ L8 ], C* t0 X
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    & Q4 h" `, y- @. o
  752.         CE_High();                                        /* disable device */
    & f1 z+ Z; G/ C6 Q
  753. }
    ! W+ w& x1 o% O+ m$ ^# [
  754. $ k$ d, [% c$ [. }: J0 b' Y
  755. /************************************************************************/0 {& c* X$ y% w4 c
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */( c4 ?9 G& r8 }3 L' s2 v/ Z% O- Y
  757. /*                                                                                                                                                */" x5 I) _4 d- Q7 P- \* A7 T7 \
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
      V: a4 r+ p7 r  v
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */6 n" v( |& C1 ]7 g" [4 ^' `! Z
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */! z$ G8 j+ {: n2 k6 y
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    0 L; L1 n; }  ^. E
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */* v* K" W& ~0 H  V' y. }. R+ k% R
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    $ ^+ e7 B: P! ^* E, @
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    2 m5 t1 f2 U. @1 N" {& Y& G; }
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    : U. Z# F: Z/ ?4 {
  766. /*                                block protected.                                                                                */& d2 u: {: n5 U2 _" c
  767. /*                                                                                                                                                */* Q3 E& x( a7 W& H/ r' k
  768. /*                                                                                                                                                */
    0 I% o/ n" g! ~. w( q/ x0 a; ^: s! d
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */! C1 j& k  r% I' ]( \8 z& s) M% {
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
      @! _  P4 ~5 ?% a
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    - _0 |1 u$ g: U2 ~* _! R
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    8 z( c' C6 R5 {3 S/ r5 U
  773. /*         last address of unprotected block, which automatically exits                 */- c/ x6 x. n. j/ L" |' E
  774. /*         AAI mode.                                                                                                                        */
    0 \7 N; F; q- W9 W( \6 Z1 u$ m- t
  775. /*                                                                                                                                                */
    0 M% Z, A- K; _9 N+ y
  776. /* Input:                                                                                                                                */' O- Q# I: ^- a, [. K* N
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */: \4 e; g  n$ [3 U: }
  778. /*                byte1:                1st byte to be programmed                                                        */
    1 e: X3 @  R5 j
  779. /*      byte1:                2nd byte to be programmed                                                        */
    3 Y- K2 J! {# W9 K4 u3 L, z6 Y. M
  780. /*                                                                                                                                                */
      \6 u6 w9 C; }7 Q' I$ _0 X
  781. /* Returns:                                                                                                                                *// U5 k# L8 D$ H; L. R2 {
  782. /*                Nothing                                                                                                                        */1 L2 t1 s- Y% O
  783. /*                                                                                                                                                */
    " z7 ?* M6 }1 O
  784. /************************************************************************/5 q( H0 X- L8 H% l. K- W3 N
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
      O8 \1 g% L0 n- W1 h
  786. {" |3 I" d: A+ X( C5 Y+ P! U
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        $ X6 V9 |4 i& B* H: N# e

  788. / R+ S, E: M4 `7 E# f) B
  789.         CE_Low();                                        /* enable device */
    5 U1 Z6 h$ R2 I8 h2 E9 p
  790.         Send_Byte(0xAD);                        /* send AAI command *// }+ i" [3 E. f  z4 C, N+ ?
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    / h; l7 ~7 y5 M2 \- ^
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));7 v0 l" h) H' [* E5 Y
  793.         Send_Byte(Dst & 0xFF);# S3 g: j4 Y: j' f% d( ]
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        ; y5 M) l( L; u  E& q* E  ]
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ! P' @( V/ I0 t
  796.         CE_High();                                        /* disable device */" _* J/ X' H! C( P, e: L
  797.        
    " E+ w# T" K6 k/ X" r1 m
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */, K% y7 u4 N2 h3 j( k
  799. 7 Z7 C& N3 M( V! K) j5 u# S
  800. }; ^+ O, r; G7 w) q1 _4 f8 [4 ~
  801.   D1 v3 |* b( d$ O  t
  802. /************************************************************************/
    ; h! w* h- g4 [$ B
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    7 Y; p) m7 Y4 \/ w7 L) ~; W
  804. /*                                                                                                                                                */) ?/ N- \! L( R4 q2 P2 M0 a
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    7 Y% ~3 G% m( \- @
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    * ^9 {; P( R% y  S
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    9 J6 [9 M  N. o- U2 f
  808. /* the device.  The 1st data byte will be programmed into the initial   */5 D1 N' E! M" K( I# A% T$ V
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        *// y! v( y+ a$ L+ _: E! }
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */  }' J5 \  w1 X* K9 U" u
  811. /* used after Auto_Address_IncA.                                                                                */6 q: L& U0 w# g  k& F
  812. /* Assumption:  Address being programmed is already erased and is NOT        */; v% _6 J# u+ j  K- x* A/ i& j
  813. /*                                block protected.                                                                                */
      j& S" I- h9 C% h! F
  814. /*                                                                                                                                                */( k5 H$ x9 E! Z$ N* @" ~* o
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */9 M- a% ~4 A9 x2 N
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */, o- a/ [( ^, e2 R4 _2 M
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    3 b2 G3 Q8 C. E# u8 k, b
  818. /*          to exit AAI mode unless AAI is programming the last address or                */2 L2 G2 Q5 ~1 v* Z+ i4 K0 L9 v5 U" r
  819. /*         last address of unprotected block, which automatically exits                 */; [% R1 R) C- ~% X% ]* i7 ~7 a
  820. /*         AAI mode.                                                                                                                        */' F5 A; U) t* o5 B  Z3 M. E: W+ z
  821. /*                                                                                                                                                */
    % b1 b) ]# }5 v
  822. /* Input:                                                                                                                                */+ {! R' r2 m( R% |1 l
  823. /*                                                                                                                                                */
    ! F) d6 X; |) M
  824. /*                byte1:                1st byte to be programmed                                                        */1 @% ~0 ~# H  u2 u" y
  825. /*                byte2:                2nd byte to be programmed                                                        */
    1 z6 R) h& t! N' O9 o2 y6 r! t
  826. /*                                                                                                                                      */( y9 W/ ~% P4 @# o9 S  k& k
  827. /*                                                                                                                                                */
    , J) J/ d. F& l# Q6 y5 D
  828. /* Returns:                                                                                                                                */
    1 A- o6 w* X& s9 A& G3 c! v
  829. /*                Nothing                                                                                                                        */" n1 x# I) Y& i
  830. /*                                                                                                                                                */
    % G. q6 ^$ p/ b  j1 m8 p" ~( h
  831. /************************************************************************// D9 }" U& ?; K, Q8 ?
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    6 R3 i' O* p/ m$ D& |- v: |+ i
  833. {8 }2 m2 \" b  A" q0 \5 i
  834.         CE_Low();                                /* enable device */* _% T  a1 [& O. R
  835.         Send_Byte(0xAD);                /* send AAI command */
    0 O3 j/ Q2 M- k
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    5 w/ o3 I' X4 n( F  `1 A4 d
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    5 d4 Q% w  ?; u6 `) ]
  838.         CE_High();                                /* disable device */
    - ^' W6 h1 S" r' J7 G' \% I
  839.   o9 c2 ?. g& b4 l! o4 z4 X) a% }
  840.         Poll_SO();                                /* polls RY/BY# using SO line */2 S& |! Z& T, G, H
  841. + B- E  ]) }. V" m4 @) H" D( L( {
  842.         WRDI();                                 /* Exit AAI before executing DBSY *// t4 g. [9 T) B6 m$ Z/ z/ S: f9 R
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI *// E: K. q0 z. J( r# h" x
  844. }
    8 g" ^/ W. |' I5 a2 x0 q
  845. 8 s+ T9 E4 N. v$ q% z% r- ^
  846. /************************************************************************/' i: y( ~6 M: }
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    & o5 c. x) C2 l) F+ V1 B; s  e+ g
  848. /*                                                                                                                                                */) a1 f0 N/ @. z8 h% J1 e
  849. /* This procedure erases the entire Chip.                                                                */, S. ?4 z; F% k
  850. /*                                                                                                                                                */
      u0 y- D; ]8 i; Y4 H& F
  851. /* Input:                                                                                                                                */3 ~/ ]- H* ?0 N- \# g7 q" m
  852. /*                None                                                                                                                        */; C: d5 x5 f" N5 j7 k; M, r7 y- v
  853. /*                                                                                                                                                */; R5 D4 k* P: B
  854. /* Returns:                                                                                                                                */
    2 ]$ d- ~* Q7 A% W. y
  855. /*                Nothing                                                                                                                        */" }) g2 ~3 K/ V% e  u
  856. /************************************************************************/
    ' r9 R6 E! m; y9 q: M# S; i
  857. void Chip_Erase()$ n; i5 `; R( y- }8 p
  858. {                                                & b! r) ^% o$ N5 V' h1 @
  859.         CE_Low();                                /* enable device */
    . o- P; \* q9 F1 C( U
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */2 y- M" j2 x( @( X& R* w6 c
  861.         CE_High();                                /* disable device */) f2 q! U% F( C1 U' i" B  ]8 a+ N
  862. }
    / X9 ~9 x* X- b- ?5 _8 T
  863. " n) Y) ^( \2 |& s: e7 A
  864. /************************************************************************/: z  o6 q% R& A; x) l' R
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    * ]. z! i" f+ q
  866. /*                                                                                                                                                */
    ( c" Y) C6 p4 }: l2 k
  867. /* This procedure Sector Erases the Chip.                                                                */
    , ^+ O; n, [0 ^, [6 t3 i
  868. /*                                                                                                                                                */! z; E, z/ ~' G6 ^4 s6 E: s
  869. /* Input:                                                                                                                                */
    $ n! b$ i( w. U2 L  n: [* M5 q
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    9 L5 v7 S  C5 ~/ h. v% i9 p7 A
  871. /*                                                                                                                                                */
    # _- c! p$ R# p, s$ ~
  872. /* Returns:                                                                                                                                */
    - s2 @7 L) l) K' }! O. [
  873. /*                Nothing                                                                                                                        */4 }8 ]) K- D+ ]! S; p6 w
  874. /************************************************************************/
    0 p: P, [5 X; I; k6 t
  875. void Sector_Erase(unsigned long Dst)% q6 ?8 t; H) g
  876. {
    6 \/ y4 d! l& J
  877. ; p4 ~: ~% @* {  D+ C! f6 D

  878. 0 s) A% h  R$ N7 n4 m
  879.         CE_Low();                                        /* enable device */
    ; e) n" a: }" y% X4 ?
  880.         Send_Byte(0x20);                        /* send Sector Erase command */0 E: r* K. B: C5 }/ z3 k9 I
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    . \5 X( G: N5 T" E; i5 q/ c
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));8 y; X4 l/ w: q6 ^5 N
  883.         Send_Byte(Dst & 0xFF);
    " k6 j7 l- x" T, y
  884.         CE_High();                                        /* disable device */4 z: I, v. ]7 S8 W- F
  885. }       
    - f3 ]2 e. R# ^6 v

  886. ( G7 Z1 @) P  f( C6 j; c$ u1 p* o
  887. /************************************************************************/; c2 {! h3 t; W; U; @
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    % w! V( U/ O1 _. s
  889. /*                                                                                                                                                */- Y6 M, y+ {# ]: W, B( Z) H& B7 M
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */" q- ?& I$ y$ s5 s& m( k
  891. /*                                                                                                                                                */- z" S, K! M) q# T9 Y) [
  892. /* Input:                                                                                                                                */
    , p( j* d) J; X" Z. _! M: X
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */5 _* T" T5 M; ]/ o
  894. /*                                                                                                                                                */
    7 {+ d& v, P. S$ w( X. w( j
  895. /* Returns:                                                                                                                                */1 i, ?( a/ v+ y9 F9 N* a6 F' B, Q
  896. /*                Nothing                                                                                                                        */
    ; P7 g! |7 K( g! s; k0 Y2 N
  897. /************************************************************************/$ d5 ]1 x+ f6 C
  898. void Block_Erase_32K(unsigned long Dst)7 H1 g" D7 P  J: I7 @
  899. {
    7 s9 l& z) H% s& i* h1 T$ |
  900.         CE_Low();                                        /* enable device */+ E3 K/ i' `% C, B% I2 Q4 T# {  Z$ c
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */9 S! m7 p. o9 f# s6 Y: b. i
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */& H8 W/ E& ^$ e5 \5 D5 T6 T- j
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 {) O% C4 Y+ o. h7 Q
  904.         Send_Byte(Dst & 0xFF);3 e* ?* j3 D2 j# W" W3 H5 d
  905.         CE_High();                                        /* disable device */5 l! k5 e- R# y, L1 W5 r  |
  906. }: j9 {* N- I+ b: d" N
  907. ( A2 A2 u7 e8 W& F# O% }0 J; o
  908. /************************************************************************/
    * A/ z; r2 a2 N$ L% J$ A
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    1 s6 l9 @! k( S! J9 H2 K6 c2 O
  910. /*                                                                                                                                                */
    + [4 s& Q3 L& ~6 J; e, G/ @; O
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    / f$ k8 ^) y, Z* z( S- T% |
  912. /*                                                                                                                                                */6 G% h; H  M! S) O' `& U( E
  913. /* Input:                                                                                                                                */7 C8 A  M6 p* V/ {5 g! w
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + c! B7 g" v& y# z. ^* c
  915. /*                                                                                                                                                */
    : v% E! e, c( O
  916. /* Returns:                                                                                                                                */
    % U! {* _- @0 N
  917. /*                Nothing                                                                                                                        */
    ! b! ~3 f/ u, Q4 W3 ]$ Q% M; g
  918. /************************************************************************/. y  d: D( P1 U9 T7 P- A+ s
  919. void Block_Erase_64K(unsigned long Dst)
    & m! ?* U) e( H
  920. {
    ( d4 z' K% G: E) y% h. R6 c3 z0 g
  921.         CE_Low();                                        /* enable device */, J& b- X/ Y( D% s: g9 m
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    1 O  m( h. v# _- k
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */, w1 D' t: w4 s- h+ S- C
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    * M* N. P& R7 h
  925.         Send_Byte(Dst & 0xFF);9 M4 G( f) M  ~: x# U! h  ^
  926.         CE_High();                                        /* disable device */$ j1 X( G! }! m6 N2 H
  927. }
    - c& b! v9 i( B( b" l: |' j+ ]

  928. + `4 c' Z- T$ K/ F- m9 L/ B
  929. /************************************************************************/
    + [) x9 k# {0 l5 l  B5 a7 T% V
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    - j  M  |, |) e% _/ G
  931. /*                                                                                                                                                */; w5 m5 m4 `1 l- w
  932. /* This procedure waits until device is no longer busy (can be used by        */
    8 l1 p! k1 }! r
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */6 _& L% ]+ U* n" w
  934. /*                                                                                                                                                */$ R6 n1 M  I3 `$ i
  935. /* Input:                                                                                                                                */
    / z: Z, Y" n( G3 f* s
  936. /*                None                                                                                                                        */
    % G- O; r  u0 s3 H
  937. /*                                                                                                                                                */
    ) z! Y' [$ l7 M
  938. /* Returns:                                                                                                                                */
    : K5 w9 V: r* k: j4 b
  939. /*                Nothing                                                                                                                        */
      K9 h6 y* o7 h  @: V
  940. /************************************************************************/
    - W  o0 `: u/ q, R
  941. void Wait_Busy()( @7 I2 G7 X1 T  d
  942. {/ w: q4 Y1 t8 v7 l
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */, z2 i! ]5 r$ O& a& G4 P. a
  944.                 Read_Status_Register();
    4 M4 k: h# T: z) N( c
  945. }
    0 l0 J# M1 J" [
  946. . U+ Y* K& U0 m4 c0 [
  947. /************************************************************************/
    ! @- g  A. \/ w0 m
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */3 \! Z5 v8 G3 Z* k" [
  949. /*                                                                                                                                                */" l$ {$ u$ D1 I1 a0 `9 K
  950. /* This procedure waits until device is no longer busy for AAI mode.        */, n- V1 G( v' R% @* i6 T$ ^4 ~" U0 u
  951. /*                                                                                                                                                */
    . I. ^1 h8 u( y& D, S" b
  952. /* Input:                                                                                                                                */: o  t, `6 E8 n$ S1 S* S8 H  i
  953. /*                None                                                                                                                        */2 B4 r$ G- Y' e- d' E, V2 }
  954. /*                                                                                                                                                */) Q3 L0 }0 W6 o# U9 T- r
  955. /* Returns:                                                                                                                                */* }6 C3 O5 }5 S, [9 {
  956. /*                Nothing                                                                                                                        */
    - G  D% Q; B& A( R
  957. /************************************************************************/
    ! |; z4 y8 u% c# w7 N
  958. void Wait_Busy_AAI()7 p! M1 E, D6 J8 Z0 i* ~
  959. {
    3 ^  x+ k/ Z0 }# G) F% z) U
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */$ e  R0 u4 F1 I) n! [* A) B
  961.                 Read_Status_Register();% l# F, M* \7 w
  962. }0 S0 W6 n/ D6 V9 z

  963. # X8 l8 \/ S; f( s9 e, R
  964. /************************************************************************/3 T; Q0 f6 @( u
  965. /* PROCEDURE: WREN_Check                                                                                                */4 r0 n) J! E  f6 `0 w$ t2 i& x5 s
  966. /*                                                                                                                                                */  M- `6 X8 u: t! ^& j( _
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    2 [! Y8 T- H, J0 [! w' ^' o# V
  968. /*                                                                                                                                                */
    0 ]7 f% z7 M; x5 N* F. G; _  x( D
  969. /* Input:                                                                                                                                */7 k. l. d5 Y+ u: }% s1 |
  970. /*                None                                                                                                                        */
    # Y7 I2 H% m1 k5 s
  971. /*                                                                                                                                                */
    $ f5 }0 i$ m  v% m& d
  972. /* Returns:                                                                                                                                */
    ; T4 K" f9 C5 X/ t6 B" ^
  973. /*                Nothing                                                                                                                        */0 h3 H. y$ ?1 h7 a% }8 s! b
  974. /************************************************************************/) I7 z7 A; q9 T+ B+ }; E
  975. void WREN_Check()
    ! d6 i+ D7 j# t8 O) u
  976. {
    , k1 f# C9 n  z4 X; b5 T
  977.         unsigned char byte;8 C/ j8 D. _9 x* y! x, t: C4 a
  978.         byte = Read_Status_Register();        /* read the status register */: m: n! _+ s, e$ ?
  979.         if (byte != 0x02)                /* verify that WEL bit is set */4 T  o9 K' Y' g
  980.         {+ L( T! L. M" m, N* o
  981.                 while(1)
    5 B3 x2 w" I- l6 {
  982.                         /* add source code or statements for this file */2 |8 n! p/ f" ]* K9 k! U7 n
  983.                         /* to compile                                  */
    $ ^" Q$ Z) c; D* @" P
  984.                         /* i.e. option: insert a display to view error on LED? */
      K+ {: t$ D3 l9 h2 i- D, Y
  985.                  1 M7 M& a3 z5 W' m9 F4 q8 K- h
  986.         }
    7 `3 L2 k+ Q! E* V/ \) h. h
  987. }
    : E4 }, l% l! n% ?

  988. ( ]1 S: ]: p$ H/ A# ~5 D5 ~
  989. /************************************************************************/3 u: l$ F) Z% _) {
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    9 i/ e! T+ a8 s5 O' c7 o$ {7 t
  991. /*                                                                                                                                                */0 Q% \. _$ R( j8 M. p0 L
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    ( p0 v) W+ x( Y0 D( E
  993. /*                                                                                                                                                */
    * c. B5 K1 g4 k+ |' t5 m0 O
  994. /* Input:                                                                                                                                */* a8 \) f2 N; \% B, }4 [6 N
  995. /*                None                                                                                                                        */
    ! E7 D" f6 v1 q- u# @9 @2 p! ~$ p( W
  996. /*                                                                                                                                                */+ k" m- g# B& @- Z7 Y
  997. /* Returns:                                                                                                                                */5 {* P. J8 q6 m1 g
  998. /*                Nothing                                                                                                                        */7 f) V1 U8 \$ s& Q. t
  999. /************************************************************************/! E) O2 r9 Y9 O. @2 h) F2 ?
  1000. void WREN_AAI_Check()  j) s) q0 V9 k' g
  1001. {
    4 X( t, k( O4 h/ M
  1002.         unsigned char byte;
    & d3 O1 [3 c9 I: M2 H
  1003.         byte = Read_Status_Register();        /* read the status register */5 m  ?9 `3 @& {& ?9 Y
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    , I  f1 I) Q2 ~& O! \
  1005.         {* r5 r9 i* I4 f/ J
  1006.                 while(1)               
    4 a7 p2 a9 Y* ]8 \7 Y
  1007.                         /* add source code or statements for this file */% ?' l! U! I  I' ~; p
  1008.                         /* to compile                                  */
    1 @1 s9 t1 s- {6 Y# G
  1009.                         /* i.e. option: insert a display to view error on LED? */% q$ a$ D# Q& e: x
  1010. # D% {1 w  ^) T1 |; ?0 @2 M8 ?! n
  1011.         }
      b) P. |" H* I4 l; p
  1012. }6 g# v6 p' V3 v

  1013. ' t' W. H8 D, I8 w" U: q
  1014. /************************************************************************/
    / V8 t% z8 Z: G0 y- q0 Q
  1015. /* PROCEDURE: Verify                                                                                                        */9 y: V( }( B! y! v) U
  1016. /*                                                                                                                                                */
    7 L. o: x$ n: ?3 s6 s( f
  1017. /* This procedure checks to see if the correct byte has be read.                */: I, C! e; a$ C% [* i& W
  1018. /*                                                                                                                                                */+ d/ r$ e; L5 Q, }% q) q
  1019. /* Input:                                                                                                                                */3 I" y9 T) y5 ^4 b4 |' B6 z
  1020. /*                byte:                byte read                                                                                        */7 z, h( z0 o0 A* a, J
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    1 v& R* n7 Q* _, C. }
  1022. /*                                                                                                                                                */
    ) W9 j  a& Q  i3 l6 P
  1023. /* Returns:                                                                                                                                */
    * l" W* g/ p9 ~
  1024. /*                Nothing                                                                                                                        */
    9 W( R  d. ]: d3 f3 l( C; C( Q
  1025. /************************************************************************/- }: G4 ^2 R3 P" d$ d" P
  1026. void Verify(unsigned char byte, unsigned char cor_byte)3 g6 i' x. Y( U7 V# f, K, h9 {" x
  1027. {
    ; ?$ Q) f, N- I# y) }
  1028.         if (byte != cor_byte)  ^, d* q( u' I
  1029.         {
    ( B/ \- G( Y4 [7 Q0 J5 K* q
  1030.                 while(1)! w( o2 m/ R. V" _! n
  1031.                         /* add source code or statement for this file */
    ) F# T* d/ t# Q4 T
  1032.                         /* to compile                                  */# Y% u! `  S$ Y* B+ y9 j/ Q/ a+ A
  1033.                         /* i.e. option: insert a display to view error on LED? */
    # V' p+ l+ w- Y" Y
  1034.                
    3 t, M3 @0 k7 P5 f9 {5 a, P% M
  1035.         }
    * g: O4 u! o0 e! ?& r% N
  1036. }
    8 A) ]/ j1 R4 Y+ v
  1037. : R' ^( d; {, B; b9 M; C
  1038. ; X) e0 r' R5 b7 s/ \7 K, ^
  1039. int main()1 Z5 w* D: [' t* Q
  1040. {
    " f) H! v: S- S: r% T
  1041. 2 b4 }9 B3 Z: v7 r: {. S
  1042. return 0;8 s+ M* w  e/ b( J) ]
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:( j( T3 P0 c1 K" H# {
   main()8 u& C: y% P/ d( L2 R& O# v
   里面怎么是空的呢?
( F2 X* }/ A6 I$ `9 k1 ^* J   发一份给我吧3 Z* S) T3 x3 J& x3 _+ C
mail:luyijun2005@hotmail.com6 b+ r& K/ m/ u$ V; `, H
咯。。。。
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。
' G3 L  f& s4 p# W$ |+ A6 w1 p  _/ Z* i# P) q3 c4 ]1 d
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
9 V7 e- j3 x: S  t" S" n+ p2 IEC的代码在哪跑,你看DS的说明,每个EC都不同的。5 w' x9 r9 B! a- K" f+ D( b8 d$ t
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
9 x( \# C$ |% u  A! F8 ]3 T上面几个问题是你没看任何东西而白问。
: z. @- [2 f- v8 F! {2 t! L" Z" h3 l& F/ n
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
8 e  V* s$ G+ X, t& ^: _2 y% i5 x$ M4 a0 O" R5 D8 C
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
9 L4 b; G- Z6 R$ I* E+ w+ Z- Q) ^/ }3 x
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”( `- h) X7 ]3 D1 Q

) y+ Y. p, f& H: P" m' n1 ^# ^关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
0 v! K! v( s& w/ D) U; q) j) a& n5 G+ H' a4 V! B& y3 B
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样/ o3 `6 T6 V1 `9 c# _
似乎要把SPI能support 到最大,这EC chip应该有好卖点) N, A5 B% A, y0 @( L/ s1 e
BIOS功能要不要强大,也就决定了SPI Flach的大小& _3 j5 G- m# ?$ j9 p3 {: b
我是这么想的~让OEM去决定要挂多大!
& J. n* G/ V9 K5 H( E, W如果我司有BIOS工程师就好了~哈! N3 p# Q* g4 d% Q) t5 z
WPCE775应该算很新的东西,来看它支持到多大?7 G) e3 B2 Z5 e% `

' z9 s! f  g$ `; Q1 N# O4 Q' f另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte/ G: g5 E. w+ m: @1 }9 T
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
# D5 x  d0 c3 h5 X- Y8 V# v, b) R6 Y  j/ w, l
这份driver收下~希望以后有用到
1 b+ x! ]( \  o! Q. `谢谢bini大大
+ }+ Y6 z: v  e9 s+ p1 J
; X1 A5 v5 U# i# l  d! k很新很新的新手,如有错误请指正 (准备看第二家的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()
; k; G$ ]3 s/ f; B" E% n{
( u6 ?$ A! T) ^" Z3 a% {1 I        unsigned char temp = 0;4 u3 `! _$ a( R( B! d
        CE_Low();7 y6 s% j, y/ p' ]
    while (temp == 0x00)        /* waste time until not busy */* j/ D$ S; K6 I8 N- X) Y: `4 i/ ~
                temp = SO;* a  S  i- H7 [
        CE_High();3 y6 j. e; }' i2 o: Z
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
1 W9 b1 E% V5 v$ H& h6 W{
( ^9 L7 X2 N. L. }9 i        2 H5 {3 T6 ]  A4 G$ B' G" W& O+ |; @- v
        unsigned char i = 0;! `* Q" y# T' @) z3 x. ~9 ]
        for (i = 0; i < 8; i++)+ j. X# v5 r! ~6 u: O* ?/ x
        {3 }0 E6 ~8 @6 N. B7 c) l8 J
               
* o+ Q* g6 j; _                if ((out & 0x80) == 0x80)        /* check if MSB is high */
. i; M/ g: C6 B0 o% B  v                        SI = 1;
7 E4 H) e8 w& Y" @/ U                else: ~+ l8 q9 l2 F5 Z2 E
                        SI = 0;                                /* if not, set to low *// u( w, j+ f1 L$ i
问              SCK = 1;                                /* toggle clock high */6 e. g, H3 p7 }1 c: g) b' B6 y" _9 s
   题            out = (out << 1);                /* shift 1 place for next bit */
6 h5 ?4 Z7 A  O, R0 S                SCK = 0;                                /* toggle clock low */2 l/ D9 r$ E1 _  t. M/ p3 N
        }
- }2 J8 r! h/ G9 W2 y. M' I}
, `1 x8 g, [1 Z# K 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-1-18 19:25 , Processed in 0.064597 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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