找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55403|回复: 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
    0 `* T' d* h" w; X  a1 O
  2. , v7 g8 f. P& F6 U1 U9 C
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    * }9 B" c5 ^, J) k; T

  4. . ~6 B+ J, d# \# V
  5. November 4th, 2005, Rev. 1.0
    6 ]3 H( M5 k. s# f  k( O6 i( M
  6. 5 _2 ]  x0 D. S5 X$ [! U
  7. ABOUT THE SOFTWARE" s7 |/ }0 v! E
  8. This application note provides software driver examples for SST25VF080B,% X3 j+ R4 u/ A, f
  9. Serial Flash. Extensive comments are included in each routine to describe
    ! H0 K4 _' F: a
  10. the function of each routine.  The interface coding uses polling method 6 y  {7 S9 T( \
  11. rather than the SPI protocol to interface with these serial devices.  The' i: Z3 B5 S% \5 F7 r7 E
  12. functions are differentiated below in terms of the communication protocols
    / z& H9 H% N: F7 W0 ]$ O
  13. (uses Mode 0) and specific device operation instructions. This code has been 3 z4 `7 u& n+ s: A1 ^3 J
  14. designed to compile using the Keil compiler.
    * K8 `; k5 v- u5 C
  15. . w4 O9 e) o0 w* e+ V+ |* s  ~
  16. : G" T& F; [9 D+ Q8 F, i* I1 x
  17. ABOUT THE SST25VF080B) u) R; r6 H3 Q0 [3 v, E: ^

  18. $ w0 u& o# y8 L9 X0 t4 Q3 V
  19. Companion product datasheets for the SST25VF080B should be reviewed in " I4 H& b+ b; v( v. Z
  20. conjunction with this application note for a complete understanding 8 q1 p( H7 C& y' y2 p
  21. of the device.9 R% x& y# ?: T5 Y

  22. " A" p1 H9 S8 `+ Q$ n7 D/ a* W

  23. 9 J- E; Y( _7 Z1 N. m; y% w
  24. Device Communication Protocol(pinout related) functions:
    % M0 |( x7 w0 F8 y$ H

  25. 3 c4 x5 w' x  B8 T  I
  26. Functions                                    Function5 K& j- k' F6 n# q
  27. ------------------------------------------------------------------
    ! X  O# b6 j9 n! m
  28. init                                        Initializes clock to set up mode 0.0 S- J" W, n% ^$ y9 F. s) |
  29. Send_Byte                                Sends one byte using SI pin to send and 0 |& b; _- I1 L3 A" Y8 e6 b, J
  30.                                                 shift out 1-bit per clock rising edge
    . a4 v! v2 w4 ^
  31. Get_Byte                                Receives one byte using SO pin to receive and shift 7 R2 b3 u8 u0 o" }) w' r) S
  32.                                                 in 1-bit per clock falling edge" I! u4 x- A. \/ f
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    7 m# R5 h. B- r8 N9 H
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    8 F' f4 K# q1 ]
  35. CE_Low                                        Clears Chip Enable of the serial flash to low5 `% V5 x; K5 U1 _2 m4 p! T$ t) u
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    & D9 t) L: k+ Y6 I
  37. Unhold                                        Unholds the serial flash
    ! V2 W; f% K$ I0 [
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    " B! i. k. `3 _2 I" ^- i
  39. UnWP                                        Disables write protection pin
    8 G0 a4 A- S" n, Q9 s- R* g* K
  40. 9 Z! R6 e* p3 I0 ~+ O6 K
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code7 d! ^4 O" ?3 G# Y
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your, @  T- ~% ^: Q" e
  43. software which should reflect your hardware interfaced.          4 N/ R9 I1 y" R$ N0 Z

  44. : G4 [: R2 I) X" Q9 i$ h; D
  45. ' F# Q( e3 |7 a- i$ }
  46. Device Operation Instruction functions:
    & G7 F% e7 x. a: v5 {/ Q
  47. # o: }% B& \& L% z1 R- @8 @
  48. Functions                                    Function
    4 f+ O6 v: F, j  @
  49. ------------------------------------------------------------------
    ( P% r/ A+ s' B6 o: E7 p4 @
  50. Read_Status_Register        Reads the status register of the serial flash
    2 @% Y1 K( V7 ]. D  s: R  X0 ~
  51. EWSR                                        Enables the Write Status Register8 |0 _* [' I; [* J& _9 l
  52. WRSR                                        Performs a write to the status register
    . L+ M! W3 l/ H
  53. WREN                                        Write enables the serial flash
    ' G- M6 p! ]6 a& }/ ?
  54. WRDI                                        Write disables the serial flash
    9 ?% E2 c6 A7 P8 n- }0 K6 F& ^
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    & ?+ M6 T9 g# s! r, W* R% X' q
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming$ x/ r+ Y, A7 c8 T! C3 z
  57. Read_ID                                        Reads the manufacturer ID and device ID
    # W( C+ |4 i* }* K1 X$ F4 l- @
  58. Jedec_ID_Read                        Reads the Jedec ID/ D$ L# n9 a2 f" p) O% a0 z& v  w7 v5 O
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    " B9 m7 y6 q& p4 q3 ]% v
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)/ c* e. ~) M3 E2 ~+ o1 y
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    # y: ^* [; O" i3 t! q
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    4 }* c* I2 m( q8 R9 A. [" l- p
  63. Byte_Program                        Program one byte to the serial flash4 M9 X7 j* f9 F  o* X0 F4 v) w
  64. Auto_Add_IncA                        Initial Auto Address Increment process, `/ y% r- o, S( i
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation0 P5 O$ R' O, S$ f3 h# d
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY$ R. M# Q. L6 @! j8 J$ Z- a6 v
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    % L" Y, h# f. R( N9 \6 p2 x
  68. Chip_Erase                                Erases entire serial flash$ Y+ q9 d$ ^& k7 [0 c
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    3 \9 Q0 d* u" H" M- [# e1 k
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash$ e( |, }0 N, ^  r5 X0 C
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    / n# s0 S3 M8 A  t2 |) z
  72. Wait_Busy                                Polls status register until busy bit is low8 c( g1 A( `+ }$ _4 ~( y/ v
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming5 n' a3 ~5 Z6 u4 n
  74. WREN_Check                                Checks to see if WEL is set
    9 t, B6 @1 l% Z4 J; A
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set, t7 i7 n* _$ }# t: F7 B) I

  76. % }& M" c( j+ z' n

  77. ( U) f6 L9 ^5 ?# ^  D# c+ ~
  78. 6 u/ @! W- r% G( b0 Y- p  \
  79.                                                                      
    - }/ a7 S! S3 }+ f
  80. "C" LANGUAGE DRIVERS $ f7 ?* d( `& c) X6 ]& k2 A
  81. ; P' f- h8 \! q
  82. /********************************************************************/
    * Q! [: G" f6 C5 }5 v$ t, `) Z! n
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    2 d2 U7 L, Z$ }+ i6 T
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    3 C- Y, Z' L: ]  N7 F" X
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */1 q2 v" Q! o1 z+ H- ^3 y
  86. /*                                                                  */- I# C1 J, v  J4 ~
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    0 _2 y4 w( y( W: {6 [
  88. /*                                                                  */+ Z% U" ~* U3 R
  89. /*                                                                                                                                        */6 O$ g. ^, d5 L/ X& j
  90. /********************************************************************/2 z' q2 L' n5 d' [
  91. ! O# G8 F; [( h4 l# t7 H
  92. #include <stdio.h>; z1 ~" n' A" `
  93. #include <stdlib.h>9 ^, r+ o* t; D. \! B
  94. * ~- Z9 A+ A( M3 G  i- s' S( r
  95. /* Function Prototypes */- \3 w3 _( N/ i) X6 a& c% j5 B
  96. 6 C. Y6 n. d  x% `, K5 N3 j
  97. void init();
    ; B8 M, Z. q  n3 \8 O* g3 T" ?
  98. void Send_Byte(unsigned char out);% q, B: X" t' F& b% l( z1 A% T
  99. unsigned char Get_Byte();
    " N( m3 a6 M4 Y3 j6 v, P$ E0 m+ O
  100. void Poll_SO();
    4 {7 R: e' {+ `
  101. void CE_High();+ f: y! }) I+ Q: E2 v: j9 n1 Q% [  ^
  102. void CE_Low();
    5 D* l2 G4 s! g# H7 v$ u1 Q
  103. void Hold_Low();* H# v& R: G* i4 I7 h
  104. void Unhold();8 r+ s/ Y' _  {7 o8 E- L
  105. void WP_Low();4 q& V7 c# C; Z9 \
  106. void UnWP();
    5 N) F5 U& x0 U/ p( E8 j# R
  107. unsigned char Read_Status_Register();
    , [- @6 V, h# f2 u  m' ^
  108. void EWSR();
      w7 Y8 }9 ^* T' y& p! @
  109. void WRSR(byte);7 Z& o& }2 q) m, r& t7 m  o
  110. void WREN();
    8 B& Q$ C& h8 K  g& ^& \3 Q( E
  111. void WRDI();
    ; `: r6 O) I, q7 E
  112. void EBSY();
    5 b) f) N, d4 \+ }' z" ~
  113. void DBSY();0 T" |) ?* O3 {8 {8 L1 d
  114. unsigned char Read_ID(ID_addr);
    - V# _. V4 P3 \. ]
  115. unsigned long Jedec_ID_Read();
    0 L& e$ U2 L: p3 A6 ]
  116. unsigned char Read(unsigned long Dst);
    - y/ q+ `5 I( q. B1 ~6 @
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    & T- L( ^7 g7 z) L) N( `, J" W! ?- U
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    8 z) x1 w; A+ d  K3 w# S
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    $ j- n, O. R' o% d
  120. void Byte_Program(unsigned long Dst, unsigned char byte);  k+ M) Z/ F' w$ p) g8 f
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    ( J/ b. Z% g0 u# U. D
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    - f. u/ \; X7 T! Z, T/ h2 I2 f2 S! L
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);- h$ d4 k4 Y; c) e) U  U
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    ) U$ q) J6 T5 T/ n- S
  125. void Chip_Erase();
    5 o0 W9 `& l: i9 A4 ~: }( a
  126. void Sector_Erase(unsigned long Dst);
    / w! u0 P* ?9 M0 w9 E% O
  127. void Block_Erase_32K(unsigned long Dst);$ o6 Z5 ^: ?" T1 @, W4 u
  128. void Block_Erase_64K(unsigned long Dst);* |! }) Y0 Z3 |' W# E
  129. void Wait_Busy();
    / G+ [! i1 J4 ]( B% M/ U4 C7 D
  130. void Wait_Busy_AAI();* H( g7 B1 o$ p$ }' X
  131. void WREN_Check();  ^6 k; r9 d+ }
  132. void WREN_AAI_Check();
    9 Q7 E4 Z, B; [2 N

  133.   p) \6 l, N& S: R) v
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    % u1 w) r0 I3 d! q2 ^0 |
  135. 4 p/ o( ]( y* H' X6 V5 v
  136. unsigned char idata upper_128[128];                /* global array to store read data */. `) d! f! M  v0 L
  137.                                                                                 /* to upper RAM area from 80H - FFH */6 ~' I9 P9 ?% B% I" Z8 F* d6 \- L
  138. 3 j! \6 J6 F8 j5 N* [* y0 w) x; B
  139. /************************************************************************/
    6 x3 i) H$ \2 r# Z$ |
  140. /* PROCEDURE: init                                                                                                                */
    ) X5 h8 G. P2 I( O/ _- M/ M* f
  141. /*                                                                                                                                                */* j) \) t0 A" {# ]& O
  142. /* This procedure initializes the SCK to low. Must be called prior to         */: Z( U' R) t$ b8 K8 \: c
  143. /* setting up mode 0.                                                                                                        */' F( t6 k! I$ R  _8 ^* r; e
  144. /*                                                                                                                                                */% k, b% ^/ [& q% [$ b7 U. x
  145. /* Input:                                                                                                                                */7 a* F7 m8 f* O0 a/ ]9 r
  146. /*                None                                                                                                                        */  m3 I% Q) d! R. s
  147. /*                                                                                                                                                */
    ' K7 o8 f  f3 J# k
  148. /* Output:                                                                                                                                */
    5 V+ G7 I$ N& ?  Y6 n! j$ R
  149. /*                SCK                                                                                                                                */
    ! Q* q  \' \# V9 @7 u: A
  150. /************************************************************************/) @3 _5 J' w* v1 _% [* \1 Q
  151. void init()
    0 ~- f. d# O  Z! j2 R
  152. {
    4 N8 a4 |: y  K# F/ q% p% C4 \
  153.         SCK = 0;        /* set clock to low initial state */9 A" R' Z" z! H$ {1 T
  154. }! b. w3 Y( B4 u9 @+ W1 G

  155. , P) p  e  W/ ~0 u
  156. /************************************************************************/7 l# S8 h& a( H9 p
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    ; ~& k- L: ~6 b" z* S3 Q) C3 U& w
  158. /*                                                                                                                                                */+ m! T4 j1 k5 v
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    , F! w' X4 K" d9 J
  160. /* edge on the the SI pin(LSB 1st).                                                                                */- R6 E1 `. }, l" b$ O- q
  161. /*                                                                                                                                                */4 n5 W; P8 ?" m6 k
  162. /* Input:                                                                                                                                */1 e/ }; o" F6 c% @2 A9 }
  163. /*                out                                                                                                                                */( R2 h( J1 P8 ]9 s) E
  164. /*                                                                                                                                                */! ?, X/ v! i; f& Z% H  L6 ~
  165. /* Output:                                                                                                                                */
    7 `, r* x" f: b# F
  166. /*                SI                                                                                                                                */( g. s: }) S- q) y7 f7 l
  167. /************************************************************************/
    8 U$ o% S$ M* f7 D
  168. void Send_Byte(unsigned char out)9 z, E5 g0 X; m. a  J
  169. {3 ?* N2 x" L0 o' U/ T
  170.         ( S% c! L8 X- G6 i. z
  171.         unsigned char i = 0;
    ! ^0 W6 P) b8 k9 r! P0 [
  172.         for (i = 0; i < 8; i++)5 }5 i3 _" U" n
  173.         {
    ! l1 s6 i) `, o& a$ Z+ q$ |2 ]6 j4 S1 j
  174.                 4 h2 `' I  c4 |- ~  S
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */3 W, E+ c+ O! V% [3 D- B
  176.                         SI = 1;+ i( G+ }9 ?1 t' }9 t6 F
  177.                 else7 G. w2 E. ?) X: `% {5 F( T
  178.                         SI = 0;                                /* if not, set to low */
    7 F$ o" j/ d  A! S# V
  179.                 SCK = 1;                                /* toggle clock high */. b; ~0 R' A  r
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    . ^8 ]( x2 U& S0 C+ O. }  ^, i
  181.                 SCK = 0;                                /* toggle clock low */) |  b, I- J3 m0 A7 ^+ }
  182.         }
    * U+ R! \0 S  v7 e3 R0 C
  183. }# q; J. f! r" f5 g& `+ E' w# {

  184. $ {; A  o! ^8 Q/ B0 R7 L
  185. /************************************************************************/
    ; r$ v; X& N) T" [" E* M
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    4 R. X' }* U3 N. s) `: ?. h# |8 d
  187. /*                                                                                                                                                */9 F3 \7 ~! u3 `" B. O! H( h
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */0 r- s- ?+ W. ~3 o; X5 ]$ V
  189. /* edge on the SO pin(LSB 1st).                                                                                        */5 K; X8 O% K3 I
  190. /*                                                                                                                                                */' d$ n" G$ S9 Z+ S" O: d' ]8 Z& p
  191. /* Input:                                                                                                                                */
    ' U" Q: D; c3 H1 ?; `( G5 ]5 T( o$ u
  192. /*                SO                                                                                                                                */0 r2 ~# q4 y' z0 j/ M
  193. /*                                                                                                                                                */6 ^" p1 P) P# e
  194. /* Output:                                                                                                                                */
    $ ~. G5 `0 b; [9 P) h1 L$ m5 y0 u
  195. /*                None                                                                                                                        */
    * D" v$ I2 B/ u2 s
  196. /************************************************************************/
    # f) G& A4 t5 X6 `# k0 i
  197. unsigned char Get_Byte()! j! @9 L; W* V9 r
  198. {
      k6 |9 m5 t, U9 g1 g" u9 P
  199.         unsigned char i = 0, in = 0, temp = 0;4 U9 S, y% C6 k# d" F2 N
  200.         for (i = 0; i < 8; i++), m. d3 r/ C+ D. c% `3 `  _2 p/ D
  201.         {
      f" L# D' U. U; E8 R) l* `
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */+ F$ B& ^$ X" Y' z
  203.                 temp = SO;                        /* save input */
    " G2 |/ ]3 J* [
  204.                 SCK = 1;                        /* toggle clock high *// ^( E# [' T2 S9 f" X( _1 A
  205.                 if (temp == 1)                        /* check to see if bit is high */
    4 {1 L4 N9 k& @2 }5 s9 ^! x0 \
  206.                         in = in | 0x01;                /* if high, make bit high */6 @! B! ?) k9 M' b8 a$ l0 b
  207. 7 s# z9 T8 r! y' i
  208.                 SCK = 0;                        /* toggle clock low */
    # U8 e0 Q4 }3 X: y" o2 G

  209. 3 M+ |# x( }6 U$ o' Q# ~
  210.         }
    9 X. N% ?, N" r4 W
  211.         return in;8 P$ G& e7 U5 i7 ?: j6 f4 Q+ y; X
  212. }
    5 p' {8 U/ F3 u0 k0 ]
  213. * k- {0 A0 X9 F; E; Q: r
  214. /************************************************************************/
    % ?# n3 ?6 p6 ?4 Z. o# e! X
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    % q" f5 P0 e) Q
  216. /*                                                                                                                                                */
    ( y% m/ {! U8 e, e$ d, V6 P
  217. /* This procedure polls for the SO line during AAI programming                  */% d2 O& U- X2 A$ d: b# F" @
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    4 B2 y" F$ M* f; Z& u
  219. /* is completed                                                                                                                        */
    1 q; P- r2 l2 V! ]' x+ F" \* s
  220. /*                                                                                                                                                */
    5 Q$ B( Z% f) i! r1 ?/ B0 H. O
  221. /* Input:                                                                                                                                */+ i9 y6 u3 H0 G2 w$ S
  222. /*                SO                                                                                                                                */( w$ m, m$ k$ n
  223. /*                                                                                                                                                */
    & @1 p& J0 T, ~4 A; W! ?% B
  224. /* Output:                                                                                                                                */. ~0 b- L! Z, [+ b2 k! \+ J0 k! [" F
  225. /*                None                                                                                                                        */) v8 \/ R9 M6 g
  226. /************************************************************************/
    6 x- ]: ?4 {( h5 f$ H
  227. void Poll_SO()! s7 E5 o' L6 ]/ \
  228. {. `- Q# q7 B8 U+ K; z1 `
  229.         unsigned char temp = 0;5 P. R& h6 Y5 X  R+ g2 F1 c
  230.         CE_Low();7 G; e( K- q3 B, O
  231.     while (temp == 0x00)        /* waste time until not busy */2 H; ]. {# x. a
  232.                 temp = SO;
    0 ]* x: ~9 F2 ]9 {; p1 a0 U
  233.         CE_High();
    $ c! w4 W& C: ]' M: z5 b/ m
  234. }) ?8 E# h" }+ `9 n$ d6 C

  235. . o$ b  C+ K. Q* Q3 q
  236. /************************************************************************/
    , }) @8 M0 v  p) p) l
  237. /* PROCEDURE: CE_High                                                                                                        */
    7 P2 J* [2 a6 n% J6 _
  238. /*                                                                                                                                                */$ ?5 {$ K. r5 I' |: f
  239. /* This procedure set CE = High.                                                                                */* o) j* E. x9 d4 m$ V: D
  240. /*                                                                                                                                                */% P9 p: u' H8 C, D
  241. /* Input:                                                                                                                                */
    % h3 G  I3 o- ^
  242. /*                None                                                                                                                        */- ^' d# k0 e0 r) b- K6 Y4 ^. ^
  243. /*                                                                                                                                                */
    9 X9 r. G( P, f
  244. /* Output:                                                                                                                                */
    6 s4 a1 @; p% v" b
  245. /*                CE                                                                                                                                */! b+ _5 i9 L" Z4 g
  246. /*                                                                                                                                                */
    8 Q# v1 ~: z* {6 a
  247. /************************************************************************/
    ; z! |; i2 s0 X
  248. void CE_High()
    5 m4 o& R, o5 ~
  249. {
    ! l6 ^& U! o: n: Q# j
  250.         CE = 1;                                /* set CE high */
    8 F, \) {( t4 V: R# h  S
  251. }, g( _3 l$ d8 P+ ?

  252. : e  l: q4 c$ H$ v' }% R( o* w
  253. /************************************************************************/
    & K, k4 {7 g1 L2 L4 }) a8 n
  254. /* PROCEDURE: CE_Low                                                                                                        */
    4 D- |, C5 I6 c/ }' o
  255. /*                                                                                                                                                */
    % z' S- R8 n% w
  256. /* This procedure drives the CE of the device to low.                                          */3 l( _5 I! W* F1 d! M% |
  257. /*                                                                                                                                                */1 M6 g* |$ g4 z  j4 p4 M
  258. /* Input:                                                                                                                                */* f4 L# _. k; A4 c0 x3 |! ?4 ?9 ?
  259. /*                None                                                                                                                        */& w8 M* x( `9 u- u, F* e; @
  260. /*                                                                                                                                                */
    : h- ?) u( d4 X2 m; G8 f
  261. /* Output:                                                                                                                                */
    ( [$ A" T) k5 \% h1 t: l
  262. /*                CE                                                                                                                                */
      L# ^# f5 \' u4 P9 U' `2 Y
  263. /*                                                                                                                                                */
    # i* h+ k5 _8 A9 z' b
  264. /************************************************************************/
    * ^; R% h% v% E# U# K
  265. void CE_Low()
    % V, J- q$ q! e+ W2 x$ t
  266. {        # h9 D( F! H$ Y; _- P
  267.         CE = 0;                                /* clear CE low */7 O# }8 O: d2 u# Y8 A5 p
  268. }% _- h" Q- Y- m( }1 m! U

  269. 4 @8 ?- n, j7 E
  270. /************************************************************************/
    % Z5 v* B; b5 F
  271. /* PROCEDURE: Hold()                                                                                                        */
    ( x+ I$ T) f$ p8 a/ w6 a
  272. /*                                                                                                                                                */9 p# r1 @0 S; P. s/ Q' p/ _4 w
  273. /* This procedure clears the Hold pin to low.                                                        */6 B% O( a  S, }# r* x
  274. /*                                                                                                                                                */
    2 N9 @' n/ U. y0 [
  275. /* Input:                                                                                                                                */
    8 H! q' e7 \" @+ q) r& P% @, d2 G8 _
  276. /*                None                                                                                                                        */  D- ~' ^: o/ \) ?4 P0 D
  277. /*                                                                                                                                                */7 n4 Z0 _" M  H* ~3 u. M$ a
  278. /* Output:                                                                                                                                */8 E+ b5 U( y1 n) f* f  v6 M) @5 V, ~
  279. /*                Hold                                                                                                                        */* H' ~% K; y% i" p4 g1 n
  280. /************************************************************************/* _9 H% z! q5 _4 Z. V7 t5 T2 `
  281. void Hold_Low()9 A2 h" ?5 R' u8 R, Y4 j
  282. {
    - |6 C' _# J. p3 H
  283.         Hold = 0;                        /* clear Hold pin */; P( {  }; S5 {% Q' s
  284. }
    , m- T& [1 f' K) C# {7 j3 I# p
  285. : r( J. Q. r8 o& X+ M& T/ q
  286. /************************************************************************/* X) Q% @! d  \2 |8 n9 g( {
  287. /* PROCEDURE: Unhold()                                                                                                        */4 d) Y7 N& g$ g7 O
  288. /*                                                                                                                                                */# N/ O" D- H. T$ H" b. z0 p
  289. /* This procedure sets the Hold pin to high.                                                        */+ G: Z9 g* R+ H/ O3 s; ^* h% b& J
  290. /*                                                                                                                                                */
    ( T4 y1 O, V$ b& i5 f% q/ @/ {% t
  291. /* Input:                                                                                                                                */' R- i$ F5 p0 J( f9 W$ l$ N& B
  292. /*                None                                                                                                                        */
    ' @* y/ R- T+ j5 q3 c; I
  293. /*                                                                                                                                                */
    + s' }; o# E0 W
  294. /* Output:                                                                                                                                */  w9 q9 P8 o; G
  295. /*                Hold                                                                                                                        */2 }6 ]5 M$ y" C7 n
  296. /************************************************************************/
    , o( |+ \; l. j8 \- O
  297. void Unhold()
    / [1 a% D3 [8 H, w+ O
  298. {7 n# W( }) t$ [3 f+ v+ Q
  299.         Hold = 1;                        /* set Hold pin */
    % f3 l4 _  C# y
  300. }" K- C# H; c! t% z8 f9 C! ]
  301. 7 a( R# J  M% `. ?: i$ V% G) u* C
  302. /************************************************************************/
    3 t% D& N- O4 |
  303. /* PROCEDURE: WP()                                                                                                                */
    & u# o- H, x. \) [1 A
  304. /*                                                                                                                                                */7 O, t' }8 a, _8 W: W
  305. /* This procedure clears the WP pin to low.                                                                */
    2 s- h, e9 d% E$ M6 R
  306. /*                                                                                                                                                */
    # l2 D( b- e/ C; X! P# ], y' j
  307. /* Input:                                                                                                                                */
    % T. K1 j0 a& v* L/ W% Z
  308. /*                None                                                                                                                        */( X% f2 Z& f0 h8 }9 C
  309. /*                                                                                                                                                */4 A: Y; a0 A7 h$ T+ X6 Y
  310. /* Output:                                                                                                                                */
    7 a& V+ @& q3 z  u  i* D) K6 ^4 Q: V
  311. /*                WP                                                                                                                                */
    / P6 q! \. H  E3 H6 x  |- L
  312. /************************************************************************/
    - l( p6 Y. T% l
  313. void WP_Low()7 T" D: _3 w: F$ [$ w" |" ~2 a3 A
  314. {
    4 j- b$ Z; f% f" z
  315.         WP = 0;                                /* clear WP pin */  d% |  o4 G$ Y! O' z' _- R6 O! `/ t  i
  316. }9 [+ ?" Z4 \1 j3 X! I

  317. 6 z6 F' ]' j. T* P# E' N8 T! k! h
  318. /************************************************************************/
    5 U- {' k" E9 N% z
  319. /* PROCEDURE: UnWP()                                                                                                        */
    # o& x; L' m( {1 W5 k7 O' C
  320. /*                                                                                                                                                */2 m/ y' V; ]7 q0 H1 i, `
  321. /* This procedure sets the WP pin to high.                                                                */3 k  Q2 s. j1 Y8 M0 a( `: V3 c- n
  322. /*                                                                                                                                                */, `: L( }4 j' |$ l: a! X
  323. /* Input:                                                                                                                                */
    / I8 {5 b" l3 ?8 j, `# k
  324. /*                None                                                                                                                        */
    / `; o/ ?( g6 p9 o, m6 j
  325. /*                                                                                                                                                */
    5 {: X5 @+ w2 N) e$ h% W' h- P9 j3 f
  326. /* Output:                                                                                                                                */
    1 h8 p& A/ _+ M. d$ ?" W  ]
  327. /*                WP                                                                                                                                */* _: q) I( i4 r. R4 K/ p0 ]# ]7 g
  328. /************************************************************************/
    * Q' \3 ^: j0 x% E1 X
  329. void UnWP()
    ; j6 }" ~$ u" e5 H- w4 P! T
  330. {
    " h+ f$ V7 G, v% k
  331.         WP = 1;                                /* set WP pin */
    6 J" S: @9 F) }8 Z% n5 z
  332. }
      E, e: d: G: C- b
  333. $ v% f1 n% Z  [
  334. /************************************************************************/5 t1 [  X7 H' B% {! f: V
  335. /* PROCEDURE: Read_Status_Register                                                                                */' ?8 [# R: H6 n6 u* l1 e% g
  336. /*                                                                                                                                                */
    / _8 ]& O0 K! O2 O; p- M
  337. /* This procedure read the status register and returns the byte.                */# K# I8 H+ `+ m" P
  338. /*                                                                                                                                                */
    0 o2 O1 x7 G1 @( w" k* L
  339. /* Input:                                                                                                                                */
    + ~7 U7 p4 R' |' s6 x
  340. /*                None                                                                                                                        */
    6 D- f! m' s% R1 Q, L! [) k& l6 q. k2 t
  341. /*                                                                                                                                                */
    , _  g: K& A% x, n5 K9 y( @
  342. /* Returns:                                                                                                                                *// [( G- u- f* D6 w
  343. /*                byte                                                                                                                        */! P# C$ S; s& \. Q
  344. /************************************************************************/# i! \( a0 {% D' l7 _& z7 E% J* \
  345. unsigned char Read_Status_Register()
    2 }% ]0 n! {( B+ x% v
  346. {6 Z) |. C- {( P! y
  347.         unsigned char byte = 0;+ |3 x9 V% M& C- _+ N! _) R
  348.         CE_Low();                                /* enable device */
    ' p/ K% X( J7 r% b2 ?1 {( ]# \
  349.         Send_Byte(0x05);                /* send RDSR command */3 [# k5 s/ _* g3 N, p+ H
  350.         byte = Get_Byte();                /* receive byte */
    4 m# r& t% l; q% Q; c" i- B
  351.         CE_High();                                /* disable device */. N, W0 |& m9 m! G) l6 _' w
  352.         return byte;
    4 {2 K* N( x: k' U7 o- @
  353. }
    7 G8 a* q* B9 Z5 ~7 r
  354. ; N; P$ e- ]& W' V6 ?
  355. /************************************************************************/
      j: U( p7 I$ k0 L2 @
  356. /* PROCEDURE: EWSR                                                                                                                */
    ( q" U* ]" ~8 y4 b( R
  357. /*                                                                                                                                                */8 g! w1 ]/ `, E3 Q
  358. /* This procedure Enables Write Status Register.                                                  */* b2 ?3 n" Z/ y) w
  359. /*                                                                                                                                                */
    7 K  D( o6 P- L$ W, L8 t. Y
  360. /* Input:                                                                                                                                */
    8 \- _' u/ u% h" I! D, R
  361. /*                None                                                                                                                        */4 D7 n2 K8 C; W; K
  362. /*                                                                                                                                                */
    ' T! n/ ?& H5 S
  363. /* Returns:                                                                                                                                */$ s7 K9 A# b( t6 l( k% Q
  364. /*                Nothing                                                                                                                        */8 I' b2 ?; J' _5 m$ I+ _) s
  365. /************************************************************************/
      U5 Q! v4 s, U5 l/ x8 l2 W
  366. void EWSR()
    : V& q5 i# C# V! W  \9 a" P
  367. {& w; `( D* T! X3 V% W" `
  368.         CE_Low();                                /* enable device */
    " N1 ~* S' k7 c! p9 Q3 I" X
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    , J" U) O* ]4 y7 _5 [- w* J
  370.         CE_High();                                /* disable device */! s6 }  u$ ^0 s$ b
  371. }3 y; [+ v9 ?9 ]

  372. 4 Z8 |9 `' ~3 X5 m
  373. /************************************************************************/
      }' z  v0 I" ]! j; q$ }
  374. /* PROCEDURE: WRSR                                                                                                                */" Q. j9 H' K3 U
  375. /*                                                                                                                                                */) S& L4 C7 {  x, c1 }7 P
  376. /* This procedure writes a byte to the Status Register.                                        */( s! o+ m: B- W; ^
  377. /*                                                                                                                                                */$ o  Y+ n+ w! D9 V3 `4 n' a% S
  378. /* Input:                                                                                                                                */
    8 g, f% J0 k( D7 C$ i1 y% R
  379. /*                byte                                                                                                                        */
    / i$ _: H/ N7 y
  380. /*                                                                                                                                                */7 k  `) Z; J4 ?5 j5 t# X
  381. /* Returns:                                                                                                                                */
    6 l2 o5 g: i- H$ ?- |
  382. /*                Nothing                                                                                                                        */4 R, U9 \  Z, U
  383. /************************************************************************/, @" i9 B$ `3 P
  384. void WRSR(byte)
    1 O' ]8 U0 z" _, m0 h" ?
  385. {2 x- w( k8 M) k( _0 V' Z
  386.         CE_Low();                                /* enable device */
    . |, c- I: s  W# f3 I' I+ H
  387.         Send_Byte(0x01);                /* select write to status register */+ ^) \3 ^6 c3 G$ @  C7 E) M9 h1 H
  388.         Send_Byte(byte);                /* data that will change the status of BPx / y5 \. p; L- e, C
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    ) p! x' E* y6 H6 a3 k5 g/ i
  390.         CE_High();                                /* disable the device */
    - U4 c9 a& f6 l* n8 ]( w. q" D
  391. }7 H( q/ \& Y* f8 d4 g! Q/ U

  392. - W/ v6 [6 u0 f" z3 g# e% c' d
  393. /************************************************************************/
    2 P% U( h9 T6 |/ y! m
  394. /* PROCEDURE: WREN                                                                                                                */
    4 c" G8 }0 W( x
  395. /*                                                                                                                                                */
    3 W1 D6 a3 }5 y9 a# c0 x, H# B
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    / D+ z1 j: R2 L; @  d. u
  397. /* to Enables Write Status Register.                                                                        */: b; Y) U* L  `0 `) P% g; N
  398. /*                                                                                                                                                */  J. b) b) W- V" X
  399. /* Input:                                                                                                                                */
    # f: v: ~- I4 @4 p# O+ G
  400. /*                None                                                                                                                        */8 D, B/ ?$ j% V* o" p- T
  401. /*                                                                                                                                                */. m! G% m+ r: F, h, R5 D
  402. /* Returns:                                                                                                                                */
    . o& p. A# H, e- j4 i
  403. /*                Nothing                                                                                                                        */' x0 H( b3 z7 `4 p( b( \
  404. /************************************************************************/2 U/ T4 t/ `' F# a2 k. w( i4 `5 @5 A4 f3 \
  405. void WREN()- M* v5 M4 l" w  R9 U% B
  406. {# g5 Z) X- J+ ~' c. O+ w$ H
  407.         CE_Low();                                /* enable device */3 W% `7 B4 G' c( T- K1 [# ]
  408.         Send_Byte(0x06);                /* send WREN command */- p3 W. v) S+ I6 S2 J. j
  409.         CE_High();                                /* disable device */4 z: A$ v. e) Z8 p! b/ ?
  410. }( r! C' ~6 F' a4 O9 r

  411. $ b8 M& c) H; G3 D! I* z6 k" S
  412. /************************************************************************/
    0 M* C/ W" n2 i3 _/ Z. J# ^$ t
  413. /* PROCEDURE: WRDI                                                                                                                */  {/ A4 W5 ~7 Q0 y5 V
  414. /*                                                                                                                                                */
    / O+ s  O2 z+ l, x  ?
  415. /* This procedure disables the Write Enable Latch.                                                */) R  }( f0 ?7 p
  416. /*                                                                                                                                                */2 Z4 F! W6 ]0 ]1 K
  417. /* Input:                                                                                                                                */1 f) f5 T$ U+ a2 R  v0 G, o
  418. /*                None                                                                                                                        */5 q6 S4 ]) w! n# i, [, O3 z3 b
  419. /*                                                                                                                                                */
    ' {2 Z' F- l* g! h4 F5 h( ^8 m2 t9 X
  420. /* Returns:                                                                                                                                */
    $ C; n4 Z' G' r0 q8 y/ `: b; ^+ y, X
  421. /*                Nothing                                                                                                                        */
    1 H, f) K/ f7 P9 \# |
  422. /************************************************************************/
    4 ?1 g1 S: Q$ f* Y6 ?
  423. void WRDI()* Q8 D( W7 U, b
  424. {6 |( e/ s# K1 d7 L5 }% l
  425.         CE_Low();                                /* enable device */# O  p$ L1 Q, l& g
  426.         Send_Byte(0x04);                /* send WRDI command */, j4 ^2 b9 h6 p* a2 ]
  427.         CE_High();                                /* disable device */" D. K3 y" {1 W$ \
  428. }- c* T' g! e' F. l8 m7 a

  429. 9 U9 c$ C7 S) f
  430. /************************************************************************/
    3 I) t7 |; p7 o% s( C
  431. /* PROCEDURE: EBSY                                                                                                                */
    $ e* Y% a' u, z; ?' j) y( z+ @
  432. /*                                                                                                                                                */
    / }: I4 S1 l3 J9 h; s! C, `4 z. ^) D. c
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */7 X9 p0 i" K; I. H8 h
  434. /* programming.                                                                                                                        */
    ! A" {3 a) ?& V2 Z# F/ ^- l
  435. /*                                                                                                                                                */$ L: T0 g' `' t7 r2 ^  H5 w
  436. /* Input:                                                                                                                                */
    3 h: W- r6 ^% n5 M! Q
  437. /*                None                                                                                                                        */' b0 D1 |9 W+ l
  438. /*                                                                                                                                                */
    + q& j2 T% W0 G6 t+ s, ~% j' l
  439. /* Returns:                                                                                                                                */" |$ t. \) I; U0 s6 F
  440. /*                Nothing                                                                                                                        */
    , v+ N5 P; W( X# o; c
  441. /************************************************************************/( m% [: J. L% f" u+ I1 k8 @; [
  442. void EBSY()
    ! N1 K  k( c; q1 |9 D
  443. {' h$ T$ t- `$ I
  444.         CE_Low();                                /* enable device */; s3 F5 d  Q9 `* T# q; _
  445.         Send_Byte(0x70);                /* send EBSY command */6 k- j$ D& [* N! g4 Z, |0 U
  446.         CE_High();                                /* disable device */3 q$ ]0 `9 L6 }7 p% p* r% R
  447. }
    * l0 J* T( @" W9 ]6 |

  448. 1 f: |+ W+ y1 h& N" V
  449. /************************************************************************/
    , M& r; j; W* Z3 `# P& d
  450. /* PROCEDURE: DBSY                                                                                                                */
    , ]0 j: G2 E& D, M4 ^( Z8 E
  451. /*                                                                                                                                                */
    ( u/ s" ~' C4 n# ^
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    ' H/ y: D  ~" v+ a% A+ L/ E2 X% B& H5 o
  453. /* programming.                                                                                                                        */
    5 t- [) k( a  J
  454. /*                                                                                                                                                */: L8 P, d; `; H9 b, M6 K
  455. /* Input:                                                                                                                                */* G# I' M: M  _) A' p, E# J
  456. /*                None                                                                                                                        */
    5 Y3 u5 P6 W! f. d. g
  457. /*                                                                                                                                                */
    # k1 H2 S+ Z! v2 u8 i. ?; e, g
  458. /* Returns:                                                                                                                                */- F4 N  H+ T, s4 d
  459. /*                Nothing                                                                                                                        */+ p6 j& W& B' a. b# Y& B0 h
  460. /************************************************************************/
    ! \  `9 W% u  e( G8 E
  461. void DBSY()5 b. f; ~' J; h7 N
  462. {
      O, T, b8 V! W7 v0 O/ O
  463.         CE_Low();                                /* enable device */
    3 T% Z& w' l$ d5 V% f! Q
  464.         Send_Byte(0x80);                /* send DBSY command */
    * M% q9 @$ y' i& X
  465.         CE_High();                                /* disable device */
    7 R# O5 o! `9 h
  466. }
    - F. q6 k. z9 e

  467. $ M$ S7 n$ g. l$ _/ ?+ ]
  468. /************************************************************************/5 {4 p" H% X! q
  469. /* PROCEDURE: Read_ID                                                                                                        */6 V0 C. K' e/ M7 y: B5 Q. F3 x1 ?6 R
  470. /*                                                                                                                                                */
    0 j# G4 ]5 F+ }1 t# }
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    : {9 P  b, N, |( c3 @
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    : c$ T0 R1 x1 H, D4 F
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    ' m# M: S& C8 H' W
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    - A* f3 d  b( b, S: \
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    ) ]- @$ |/ q8 N! u0 R& I/ l# R- k" t' m
  476. /* variable byte.                                                                                                                */' ~+ ~' D. o, q9 ?+ I5 e: X# `
  477. /*                                                                                                                                                */
    5 L0 B5 P8 X) Y3 [, I
  478. /* Input:                                                                                                                                */  I* h) G7 U2 O6 X6 v# D
  479. /*                ID_addr                                                                                                                        */3 u: d  A: x2 v! ?) w
  480. /*                                                                                                                                                */
    4 n9 d; _. c& {% M0 {* ~
  481. /* Returns:                                                                                                                                */# f/ v% c1 R* l& Z; n. d6 t# L
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    ! }7 X, n. u2 p' g+ V' V
  483. /*                                                                                                                                                */
    " T% O1 z- t4 {0 C
  484. /************************************************************************/
    7 J% G: }! F% L7 H1 e2 ~! q
  485. unsigned char Read_ID(ID_addr)' r8 j+ i% F& @3 i) \
  486. {
    / p  a- l* y, c+ E* N/ Z% l6 U, v
  487.         unsigned char byte;
    4 c; X% r  ^$ A) M/ u1 u% h
  488.         CE_Low();                                /* enable device */, w0 x0 c! D/ F9 k6 ^: }% w
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */: @+ I: F" g% a' O
  490.     Send_Byte(0x00);                /* send address *// Y1 F$ r6 p8 y" x, N
  491.         Send_Byte(0x00);                /* send address */
    - [" E9 v" {& z- r
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    9 j: Y/ z) q/ `; S
  493.         byte = Get_Byte();                /* receive byte */
    ) ^/ x$ o7 h1 L% E0 k
  494.         CE_High();                                /* disable device */- m4 ?8 j. t% X
  495.         return byte;1 M* Y2 k. A8 J0 i  m; n
  496. }
    0 N; u+ ^% R1 h' O+ v& ?# v
  497. ; F5 H; R/ \3 h8 Y
  498. /************************************************************************/
    & x& Q# {6 W4 O1 l  t1 H
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */  X. ^  x7 s' z6 d' z! b
  500. /*                                                                                                                                                */
    5 a! ?! S6 m2 a) W) @! T
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    ' v+ W# n" z$ `5 Z7 I
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    : _5 \! T" Q1 z: h6 ~2 u/ W
  503. /* Please see the product datasheet for details.                                                  */
    6 `6 y: c* s2 `# l' T+ d+ ~9 u! h
  504. /*                                                                                                                                                */
    % K& {& E& A+ W
  505. /* Input:                                                                                                                                */; f  V1 S: R0 c
  506. /*                None                                                                                                                        */0 G) J8 z# j- K( ^
  507. /*                                                                                                                                                */
    3 i2 L2 V+ d4 E" I3 [- j
  508. /* Returns:                                                                                                                                */! Y- n( p( i, }( ^
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        *// o: v4 q5 H. z* n8 b
  510. /*                 and Device ID (8Eh)                                                                                        */- D+ e4 _8 d2 e* {% u1 ^" `9 Y
  511. /*                                                                                                                                                */  k- ^/ c' {8 a$ L: d# k. k
  512. /************************************************************************/) p( Q* p" `1 e# g7 w8 s$ G
  513. unsigned long Jedec_ID_Read()
    8 G; p7 f% p& ]8 h: a
  514. {
    + {# @1 j5 s. A7 r4 e) z
  515.         unsigned long temp;6 G& G0 L3 K* @) ?' R6 q+ w/ A9 s
  516.         + A6 j' I# m5 E& v
  517.         temp = 0;9 D7 s: F8 n  u; ^( {
  518. 1 u6 v: y& Z' }9 d+ s6 x  v
  519.         CE_Low();                                        /* enable device */
    - O) f2 m8 X- d* e
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    " i* z0 F/ _) a; s* z2 o
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */$ z7 ]0 O6 X: q4 N6 @
  522.         temp = (temp | Get_Byte()) << 8;       
    ' q0 q6 s4 ~4 b. B! h4 ]
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */# }) s, u. g! c. Z: a
  524.         CE_High();                                                        /* disable device */  e; E+ J+ I  C2 J+ t. i
  525. - D2 S( J# \  N4 o% h: s
  526.         return temp;
    3 R# R8 L, A. L  n% e, \- S5 `+ N
  527. }* S* X, z7 c9 s, i/ D

  528. 8 ?" A5 Y" D4 @2 B
  529. /************************************************************************/
    8 ^3 a. o/ P: L4 @2 R3 x+ X
  530. /* PROCEDURE:        Read                                                                                                        */
    # T7 R1 ]2 j  l3 \; ?
  531. /*                                                                                                                                                */                ; c  i% k' K" K) `
  532. /* This procedure reads one address of the device.  It will return the         */
    # \, W  G# }( M3 ^
  533. /* byte read in variable byte.                                                                                        */) K# \. `& W+ Z; @
  534. /*                                                                                                                                                *// i5 }4 {1 D8 W, y
  535. /*                                                                                                                                                */
    0 N6 Z8 _- Q0 @4 \; _& m4 ]& t, v. w
  536. /*                                                                                                                                                */
    + p) K4 ?' [+ R' g6 Z& Z
  537. /* Input:                                                                                                                                */
    + ~7 p3 `) C3 J5 d3 v6 `7 y- `3 v
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */8 g, h! a1 x, o, e& `0 K
  539. /*                                                                                                                                      */9 s. k6 f9 }0 \/ I9 G' J0 d' J5 L# h" N
  540. /*                                                                                                                                                */
    $ V& y  l) X* _; P3 B
  541. /* Returns:                                                                                                                                */- z" I. b9 F+ l$ P$ F& k# n- V
  542. /*                byte                                                                                                                        */$ y& _8 c% ?3 n& `% R$ E
  543. /*                                                                                                                                                */  U' ~% ^" L4 C& S3 C
  544. /************************************************************************/
    , ]! p3 k' q! S- ~5 K  z
  545. unsigned char Read(unsigned long Dst)
    2 {5 s& s  f1 d
  546. {
    ; V1 w- t. i8 L. o9 Q/ [) y
  547.         unsigned char byte = 0;       
    - e! z2 s! o% D+ ?/ @% P

  548. * t. y. H  L7 k% |% D4 n% f% T$ p
  549.         CE_Low();                                /* enable device */% d5 u! _3 ^( I5 w9 W4 Q
  550.         Send_Byte(0x03);                 /* read command */5 Q% ^3 Z  f9 F8 B1 {; ?1 _
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    . y+ R3 _$ B& N9 i3 _. U# ^
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 }0 O" m; T; W& ~( \! j
  553.         Send_Byte(Dst & 0xFF);
    7 ^- J5 p4 i* l) E# T  n5 X) y
  554.         byte = Get_Byte();
    1 ~7 q/ M  u/ f' ]4 ^1 {
  555.         CE_High();                                /* disable device */: K5 s! t- W" }% ?2 t7 p
  556.         return byte;                        /* return one byte read */
    7 k) v3 A8 K' H# O+ d" {- U
  557. }
    2 ~$ \6 [+ m$ L: Z/ X
  558. 6 r$ D7 Y# {2 K! h6 p* j
  559. /************************************************************************/$ L) r6 k/ J% J
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    + G& R* P4 i( T/ n, o% f# f
  561. /*                                                                                                                                                */               
    : V1 Y* c( Z# c, Z; V8 y
  562. /* This procedure reads multiple addresses of the device and stores                */
    , J, S8 w4 F6 Z5 Q
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    $ `' b) F; f5 B* Q1 M4 j
  564. /*                                                                                                                                                */
    5 y9 w) k" G9 N5 m8 p6 h
  565. /* Input:                                                                                                                                */$ z4 Y4 A9 u4 G: q4 P+ f, J
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    7 t# v. t$ M6 o# x# ~' N
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */% _; k4 R: s) X; s; {
  568. /*                                                                                                                                                */
    , \. {  f+ P" F# a2 H2 s) Q
  569. /* Returns:                                                                                                                                */
    ' E- {4 l/ c5 Y6 h& S. u5 @4 [
  570. /*                Nothing                                                                                                                        */& V! H: y, ~' C) `( {8 v) x6 j
  571. /*                                                                                                                                                */6 R- S% }! a3 E/ ~' H
  572. /************************************************************************/4 ^* m' m: m$ D& O
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    $ [4 Z0 J3 {9 B+ Y
  574. {
    ! Q. M" t: J1 ]* V& u$ ?
  575.         unsigned long i = 0;
    7 ?! p+ z. ]# o3 d- [$ w8 j
  576.         CE_Low();                                        /* enable device */
    6 |# v7 Q9 ?# g- [+ i9 z
  577.         Send_Byte(0x03);                         /* read command */) a3 N- f! ^2 R/ L* B
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */3 _8 U( Z' [& r0 `' P. T
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    # n: }' ^5 p' T
  580.         Send_Byte(Dst & 0xFF);5 k$ P: Y9 z1 q# q$ L) A
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */3 J3 Z  d) _7 ~+ G
  582.         {4 M/ C; B: w# k/ P2 M
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    - k: S, ^  }+ R+ a
  584.         }
    7 d* L! A9 O* m( u% K& q
  585.         CE_High();                                        /* disable device */
    2 n' y* l7 A- F: L9 T  C% P( v

  586. * O9 @' x! a' Y7 ]7 x3 x
  587. }
    7 O1 D. n4 t, J; ], S. R4 H
  588.   C6 B* V" Y5 M+ @6 \% F5 C6 p+ [" `
  589. /************************************************************************/
      K; `' [1 N$ x
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */$ n# }; F% K- ^
  591. /*                                                                                                                                                */                2 a% |7 X2 Q4 p7 b9 f) |
  592. /* This procedure reads one address of the device.  It will return the         */2 R1 E, @9 \- W; W" f4 o
  593. /* byte read in variable byte.                                                                                        */) C' Y6 ?& a9 i+ \
  594. /*                                                                                                                                                */
    1 q2 x- N) p* S8 t& f6 _
  595. /*                                                                                                                                                */
    " g9 W' i+ G* C6 E& t( [' M# U/ I
  596. /*                                                                                                                                                */
    ' B, f# n+ a* `- j- i
  597. /* Input:                                                                                                                                */+ L" z. }# Y$ x7 D& R
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    $ d2 R/ B1 Y2 M2 F4 Z
  599. /*                                                                                                                                      */
    0 g# C3 `0 a' |1 o+ P; v) J
  600. /*                                                                                                                                                */; L  q5 ~4 W; ~  i& k: M. ^
  601. /* Returns:                                                                                                                                */
    0 \; _4 @* v# I) P, p
  602. /*                byte                                                                                                                        */6 r( i" V" q( b5 [  P9 c+ E
  603. /*                                                                                                                                                */1 {; ?* p4 s1 z- w0 \0 J5 D! _. K
  604. /************************************************************************/
    6 q! z1 l2 S- t7 U8 x
  605. unsigned char HighSpeed_Read(unsigned long Dst) 3 p. W  F* ^: h9 _
  606. {
    / V+ h, d" W$ _0 x( U
  607.         unsigned char byte = 0;       
    " L4 M* Y2 {' C, k$ W( L" E$ g
  608. + @' f9 T$ _+ n) x. ]% I
  609.         CE_Low();                                /* enable device */. V" E8 t* v% _1 A
  610.         Send_Byte(0x0B);                 /* read command */: g8 W. Z% e- F& G7 i& u* q
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */- J" Q2 i$ w% x- X; T1 I
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % P' F" P4 Q* p3 I3 u* ~- z
  613.         Send_Byte(Dst & 0xFF);+ w2 M5 f8 ]6 L% c" [" m
  614.         Send_Byte(0xFF);                /*dummy byte*/9 H1 J3 ~4 F2 B9 `. J/ d
  615.         byte = Get_Byte();
    $ V; @( N! ~% \1 p  Z& [8 K9 j
  616.         CE_High();                                /* disable device */! I  b- c0 v/ a4 N3 ^/ D
  617.         return byte;                        /* return one byte read */
    " T7 A) @. F/ |% l
  618. }
    8 j5 q( ^! C8 E) U/ C# Y6 ?
  619. 3 O4 _6 ]7 Z4 j* `9 c. s
  620. /************************************************************************/
    # r, y; S- e" c: V% D
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */' `. `* g, q" ]' A
  622. /*                                                                                                                                                */                # G* G) a2 a9 s
  623. /* This procedure reads multiple addresses of the device and stores                */
    ! ?& _& k$ t8 M/ f1 Q# L( V! o
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    9 p4 L" e7 ~' G  ?, P9 v' J$ L
  625. /*                                                                                                                                                *// s- ]- t  z+ Z. l
  626. /* Input:                                                                                                                                */
    5 K7 k9 C2 {- F: t9 p# b
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    % o4 m3 @$ |3 W+ Q9 W
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */2 K% M$ L; h; {+ H2 j
  629. /*                                                                                                                                                */6 y! J) ^% t$ [
  630. /* Returns:                                                                                                                                */
    # H% y% J  E1 ]4 X! Z
  631. /*                Nothing                                                                                                                        */
    9 A% t2 V, l# T5 s
  632. /*                                                                                                                                                */
    4 L1 ~; k! `4 m
  633. /************************************************************************/
    ( a! B& ^. _) Q3 O
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)0 I; T7 h  q* U; x* R
  635. {9 b4 I' j  T+ H5 _
  636.         unsigned long i = 0;
    . m% R; T: g4 e: E7 c" |
  637.         CE_Low();                                        /* enable device */6 E4 n1 Q5 U+ G. Y/ X  Q8 Z
  638.         Send_Byte(0x0B);                         /* read command */
    1 D/ Q) U8 y* Y# o
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    7 j# W9 I7 t3 G/ }5 \; }
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));8 D9 E( _0 }1 y: g
  641.         Send_Byte(Dst & 0xFF);% k- H% ^0 x2 L$ q$ S6 E, i2 R; |
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    2 e! o7 R! C( f1 F) t
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */, p  c9 d5 `$ N( H5 `
  644.         {
    7 E) a% E; ~- c, x0 Q- D
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    * X% R4 `. s/ o9 f
  646.         }
    ' L5 d* \8 P$ h. W& ]
  647.         CE_High();                                /* disable device */
    8 N$ v# t9 b4 J" b( O; J; I
  648. }
    6 b- ~! K6 E' f* X8 J- c, m
  649. : k7 l, R( _% X; k" u6 X0 Y5 ^" z
  650. /************************************************************************/
    / h; j1 ?1 E# c8 x9 r
  651. /* PROCEDURE:        Byte_Program                                                                                        */0 B( f4 g9 R  r( [4 I" d) f
  652. /*                                                                                                                                                */
    ; W0 T. F$ d( S% P: \
  653. /* This procedure programs one address of the device.                                        */# |9 a4 D6 s! G8 u) r
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    , n# k+ K1 `% S, e% h/ U4 L
  655. /* block protected.                                                                                                                *// B3 _  V% z, q4 f1 V# s
  656. /*                                                                                                                                                */
    # h/ r9 g2 r: g$ ?
  657. /*                                                                                                                                                *// Q+ s  W- u  D! Z# [- E8 P
  658. /*                                                                                                                                                */
    5 q3 U' O( e9 l7 `
  659. /* Input:                                                                                                                                */
    . [& K0 W+ S6 |% r1 p
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    5 J9 z' Z/ p3 P) R  Y3 [
  661. /*                byte:                byte to be programmed                                                                */
    6 b& J  O8 v# \, Y  V) O
  662. /*                                                                                                                                      */' H7 X: \. A' R& L: Y6 C, h
  663. /*                                                                                                                                                */. d- E. V+ k3 I0 }) H. _# Z4 J1 c
  664. /* Returns:                                                                                                                                */
    / ]) b. F! w& r* }1 e/ D5 Q
  665. /*                Nothing                                                                                                                        */
    % Q2 d' |+ t: o
  666. /*                                                                                                                                                */  ~( ^$ N/ L5 z  z
  667. /************************************************************************/
    ) k8 b2 @( q; V# _% r* L+ S8 J
  668. void Byte_Program(unsigned long Dst, unsigned char byte)9 p/ D% _1 s0 r# U+ X
  669. {2 Q" t1 Z" Z, k. j: I! X3 j1 m2 u& `
  670.         CE_Low();                                        /* enable device */
    & t/ {4 E- ~5 p; G
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    : U1 n# J, d4 n
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */- `. `1 ^" ^$ H2 Y
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    8 @* h8 j9 F1 e( \0 y* w9 e& v( R+ n
  674.         Send_Byte(Dst & 0xFF);8 q3 e9 n/ p2 j5 o9 w: l2 [4 i) q" g
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    $ \/ r* f5 T! c+ F3 q
  676.         CE_High();                                        /* disable device */
    6 X% F5 J" N. V$ v' Y/ L3 [
  677. }! g# |$ ~) U* ~+ A1 J; |  e3 U

  678. % m5 s- C$ A- Z
  679. /************************************************************************/) o* r  U+ M  \+ ^: L5 v, G
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
      O9 L' y4 d- U
  681. /*                                                                                                                                                */
    ) `# w! I( ^! F+ v; k) e7 J( S' V
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/8 |/ a4 A8 E) ?& J7 Y
  683. /* the device:  1st data byte will be programmed into the initial                 */* n  r9 s/ R% r  I2 V: B
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */  c4 z# A/ g2 O+ l4 q
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    / r3 F  Q* x, Z* p
  686. /* is used to to start the AAI process.  It should be followed by                 */
    ! F3 `6 v9 l4 h0 z9 w* {
  687. /* Auto_Add_IncB.                                                                                                                */  K$ a; s0 p; y/ m7 D, B
  688. /* Assumption:  Address being programmed is already erased and is NOT        */2 z+ G' N2 y, E8 m$ O; }
  689. /*                                block protected.                                                                                */$ S9 c; w$ X/ M  K/ X( E" q
  690. /*                                                                                                                                                */* R" {5 L* Z  }5 y+ v$ g
  691. /*                                                                                                                                                */
    # m5 p9 A+ _. H2 h) y! h9 y4 O: d1 t
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    4 J% \2 [% X% C' u
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    % q; D  o5 ?6 p; s, n4 t" z- s8 C
  694. /*         unless AAI is programming the last address or last address of                */# q% Y- S( H. S- F
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    $ B( N1 ^  g" C" r
  696. /*                                                                                                                                                */
    % G/ n/ r! X$ U, m% F! p
  697. /* Input:                                                                                                                                */) g3 n9 ^6 p. V  }3 H( `
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    6 \/ ~4 d6 [( J& A/ v& {
  699. /*                byte1:                1st byte to be programmed                                                        */8 e/ X9 h- j( B4 u0 ^
  700. /*      byte1:                2nd byte to be programmed                                                        */2 T6 n2 R& \5 J0 W% d! S4 k
  701. /*                                                                                                                                                */  H1 |4 U4 A* h. F; Z  i
  702. /* Returns:                                                                                                                                */. D" C# T4 r) h, N/ K
  703. /*                Nothing                                                                                                                        */, e, B- d/ \1 T. h, z
  704. /*                                                                                                                                                */3 l8 N4 E6 N- z, w
  705. /************************************************************************/- R0 _8 q) h" c/ U2 W
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)) j" k0 H9 @& [% m
  707. {
      @) {  E. @: Y: g/ y; i/ q
  708.         CE_Low();                                        /* enable device */
    ( ]- K5 L# a/ H
  709.         Send_Byte(0xAD);                        /* send AAI command */
    . s2 a" v  ^7 M+ R6 `
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ' d3 Q) A; u: A& q
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " J! o" V8 J' [) R5 w+ T# J+ j) E
  712.         Send_Byte(Dst & 0xFF);
    3 a, l5 s" M. `# W1 M  F
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        ; U8 [* R& J: L$ V
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    : B8 S6 e) f9 _/ I+ h" `# k7 T
  715.         CE_High();                                        /* disable device */
    2 `" E- F! O1 a7 C
  716. }8 n& I! n- [, k5 F3 Y/ ?/ _4 s0 y
  717. 7 k2 h, S- p* i0 J( P; z& R
  718. /************************************************************************/
    7 }6 e% F% g" K9 p0 d9 U) S
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    % w* u9 u7 ~8 F/ m" L- M" {  U
  720. /*                                                                                                                                                */
    ( u1 t2 w3 U7 {8 w) q, N
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/: V$ P7 M4 a! @' r
  722. /* the device:  1st data byte will be programmed into the initial                 */; U/ x- e7 F3 [9 }2 N
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */3 F5 N/ n# ~3 h8 J
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    / S& j0 A" T+ u- e/ N% J
  725. /* is used after Auto_Address_IncA.                                                                                */2 |, m) u& y2 Y" u$ `
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    " r, l$ D7 b8 W2 Q$ R
  727. /*                                block protected.                                                                                */& Z) c8 t; S4 c5 R6 d- f" u
  728. /*                                                                                                                                                */5 N+ ?+ `9 W" _6 X( X! Z
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    8 t6 w( [, |& G$ }1 [) p
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    3 t) _8 ~$ T( z5 }: [- H% i
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */6 w% G6 r# R$ V" B
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    6 [% l% I  v) n
  733. /*         last address of unprotected block, which automatically exits                 */* k7 ], X+ n2 @) U! z. c& z8 n! ]
  734. /*         AAI mode.                                                                                                                        */$ A0 ^. q0 e/ I$ o; u" r0 m
  735. /*                                                                                                                                                */5 h  S6 {, z  {$ e1 b2 }  w  e! h
  736. /* Input:                                                                                                                                */
    " v: j; {6 J6 q7 F$ F8 F, N3 l; V
  737. /*                                                                                                                                                */7 r" E! ]/ L- W' C$ R* r# u- ]
  738. /*                byte1:                1st byte to be programmed                                                        */; C9 i7 d6 j) Q1 X
  739. /*                byte2:                2nd byte to be programmed                                                        */+ B" X% b! _. ]. a9 y+ ]* \
  740. /*                                                                                                                                      */% c$ w. P" Y" y, k# z/ I. Q& [
  741. /*                                                                                                                                                */* {; i/ z. A/ {* O  j
  742. /* Returns:                                                                                                                                */
    " c' _3 R- y3 @
  743. /*                Nothing                                                                                                                        */
    + A/ V" b) F& S# \7 K" ^
  744. /*                                                                                                                                                */9 D+ d  o: d" O0 N' K
  745. /************************************************************************/' \# H% Y" {+ E3 v8 b( s: r3 H
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)0 Z1 `( |# ?. E  ~; F+ D5 z) c
  747. {* C! h7 y0 \5 C
  748.         CE_Low();                                        /* enable device */
      y; H9 a; d, D8 Z6 h. s
  749.         Send_Byte(0xAD);                        /* send AAI command */
    3 G, M3 ~! y/ C9 L; Q
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    5 g7 p( W  S% |; f8 R& H1 t9 }
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */* A( g$ r; z  I# e* n$ y( \
  752.         CE_High();                                        /* disable device */1 Q+ F6 S& H3 l2 ]; m
  753. }& Q1 k1 K1 g  {4 d

  754. 9 P+ J0 @( U3 A/ F
  755. /************************************************************************/
    % a: p  r/ n3 ~1 @+ C$ Q
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */, [6 Y8 n6 r0 @( C
  757. /*                                                                                                                                                */  c" U- _" p% O4 U
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */* A4 v( S1 s, B; o0 o! |7 U. x$ h
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 *// M. H2 D5 F/ \' Z6 F! I( |$ b0 ^$ n
  760. /* consecutive addresses of the device.  The 1st data byte will be                 *// i. x9 \, w) Y9 w$ C* e$ M
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    + j( P; d% L# ^+ a* j4 I
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */1 {- Q- _8 D% ]
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    ( `2 E7 c- n, }6 \' B0 N) G+ z: d
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */; q$ O: z' i$ B- P
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    3 g! f0 Q. e  U. W2 P
  766. /*                                block protected.                                                                                */9 K7 V" {9 p9 V; ]
  767. /*                                                                                                                                                */8 w: Y  e3 v+ E2 F+ x5 ^% v3 L
  768. /*                                                                                                                                                */
    # L( T! a$ q4 k4 K' w& C8 L
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ; X* M, ]  S. K( c- }
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */) H0 C0 j; o! t2 u
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    . T. d, Z% L/ r7 A6 I2 P0 W+ J
  772. /*          to exit AAI mode unless AAI is programming the last address or                */+ z7 r# M" o( r& _# {" I
  773. /*         last address of unprotected block, which automatically exits                 */+ [8 ~& o5 u* @" B* p& b# K& k1 P9 l
  774. /*         AAI mode.                                                                                                                        */+ l! c# Z6 K0 H6 R: E" X5 s4 c
  775. /*                                                                                                                                                */
    ! L% T' M; k+ f& n
  776. /* Input:                                                                                                                                */8 ~+ U6 Y. k1 c$ f% O% W) H7 e1 k
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */, a% i3 Y% K3 c8 z" }; ~3 L
  778. /*                byte1:                1st byte to be programmed                                                        */" y4 ?! t; C* \6 ^% u# s
  779. /*      byte1:                2nd byte to be programmed                                                        */9 R; @4 T, E+ ~6 ]: N% N# F0 J4 r
  780. /*                                                                                                                                                */
    % s8 B* O* Q0 g. e2 ?) l
  781. /* Returns:                                                                                                                                */
    5 s, ]& v  w. p: u* W. \2 s
  782. /*                Nothing                                                                                                                        */
    $ T9 [# j- }9 \/ k9 {+ \  h! v
  783. /*                                                                                                                                                */2 M! W* {0 n7 J/ t3 }
  784. /************************************************************************/
    0 M; ~% v- k0 {  p
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    + i5 H/ B- V. R( i
  786. {+ I( o# l( X: T& F
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        , P, X- i& q1 V5 x; J% t
  788. % q% _6 J. y$ F- @; M! Z# y: T/ p7 E
  789.         CE_Low();                                        /* enable device */
    2 M1 A9 o6 @5 ^/ j% x4 ~
  790.         Send_Byte(0xAD);                        /* send AAI command */
    . S8 V, O. t! v6 t+ d' Q0 M
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    4 M( ~4 h, L) k% \$ m
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ' I0 T0 M: A' i; x+ K1 s, n: ]2 q
  793.         Send_Byte(Dst & 0xFF);" q2 F4 D: i6 O2 L
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    + x/ L+ l% V+ `$ P. n
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    # T; _# r1 D6 Q0 Q) D; @& [+ E
  796.         CE_High();                                        /* disable device */) O/ }$ [) e/ T3 U/ ]6 H+ V
  797.        
    1 H! w. f; j" Z
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */; }; e" A) z$ |& {

  799. 8 ^3 y% L* F" L  X- B  o
  800. }3 H. e! p" V0 A: o% l

  801. 4 A! r! m. [5 S* S: u% c5 o
  802. /************************************************************************/, ^% g/ g: C! s3 H
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    1 U) }. b: S" A3 J$ H2 P
  804. /*                                                                                                                                                */. l2 \- R% {* _
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 *// V! `& I# G/ D" i0 \% @$ \
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    8 V4 d3 z6 m- `8 H% c2 }' _& {
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    : m7 e- c5 W$ G( x
  808. /* the device.  The 1st data byte will be programmed into the initial   */( N5 k* m. j- m; \% F' w
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */, O! @' j- `+ j7 `: k" {: G
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    / w  K* O" |& G# f, o- Y+ y
  811. /* used after Auto_Address_IncA.                                                                                */
    7 X, [/ O8 Q0 V3 C+ `" K! N
  812. /* Assumption:  Address being programmed is already erased and is NOT        */7 V  [: A0 M+ O7 n; M6 h
  813. /*                                block protected.                                                                                */
    3 t9 {/ G4 T( @; `$ r) z5 k; B. ~
  814. /*                                                                                                                                                */
    9 R" L* P/ [4 b6 C; I8 [! S$ `( [) z1 |
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */  ^( k+ X6 `, O. ~
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */4 W) z; _1 M. ~. B; D
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */' c2 @4 w) M, y* {' t
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    0 I- E9 u. l2 Y. p% z
  819. /*         last address of unprotected block, which automatically exits                 */
    ) {9 ?! B: f8 H. |  }/ C; k
  820. /*         AAI mode.                                                                                                                        */# O$ ?0 h/ p5 Y; J2 L" J/ g0 Q
  821. /*                                                                                                                                                */
    " s* F9 E. D8 V( \; r8 r# k# L
  822. /* Input:                                                                                                                                */
    " k$ T3 o& q3 r& S3 e3 ?
  823. /*                                                                                                                                                */
    ! c+ }$ I0 F$ k, o0 }  ~" W
  824. /*                byte1:                1st byte to be programmed                                                        */
    * o8 T* V( r3 s/ l- c" N
  825. /*                byte2:                2nd byte to be programmed                                                        */
    " h. U  L  C1 G6 L
  826. /*                                                                                                                                      */  t& G  Q* @! O7 O) ?! E& }
  827. /*                                                                                                                                                */; g! I4 n2 N# y, ]5 w
  828. /* Returns:                                                                                                                                */
      y, S; n/ n0 Y
  829. /*                Nothing                                                                                                                        */2 K- ^1 t8 U  n; F
  830. /*                                                                                                                                                */
    6 |2 |4 W3 {; Z* J
  831. /************************************************************************/
    7 ]+ h( T: V. o& ~* ]6 Z8 U
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)' X6 _, k8 b, p
  833. {1 N& c! o( [, h1 S! ?
  834.         CE_Low();                                /* enable device */
    - |" Q4 H0 k1 _7 b8 A" g$ s  f4 v
  835.         Send_Byte(0xAD);                /* send AAI command */
    0 ?+ i* L* Z' k: X
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    7 G* S$ Y, W8 i3 F: z4 y! W1 e' s
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    9 z% e9 b7 J+ W0 O/ A0 l7 @! A
  838.         CE_High();                                /* disable device */
    4 u6 @8 H) M8 L9 ~* ^
  839. 1 K" r! L+ {4 S/ P7 i  F- `
  840.         Poll_SO();                                /* polls RY/BY# using SO line */( B7 \0 j6 }& s) [/ e7 b
  841. 6 J7 P! M* W) c- n$ E/ c# \. i
  842.         WRDI();                                 /* Exit AAI before executing DBSY */- x2 B$ `" T( T: |& D# ~
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    $ ~6 f* G0 Z* X9 h/ p/ D1 h* ~
  844. }% L% |4 w* W6 ^& C% T9 V7 j- F  l
  845. ! D* ?0 B* z* Y5 s* a' ^8 X
  846. /************************************************************************/+ Q' p1 ?4 F% r8 L, m; A
  847. /* PROCEDURE: Chip_Erase                                                                                                */* p2 c4 d; z- a' F6 |) n: Z! \
  848. /*                                                                                                                                                *// ^+ _) [  l( r# f. m$ L! u
  849. /* This procedure erases the entire Chip.                                                                */* ^* k1 N, c7 t/ p
  850. /*                                                                                                                                                */& z  ~0 Z: L% ^  }- R3 X6 m; x
  851. /* Input:                                                                                                                                */. ^2 j: i% p' m# i' \* e6 Q
  852. /*                None                                                                                                                        */
    ( ?3 Z( w! C4 E/ F+ q' H
  853. /*                                                                                                                                                */7 \# v5 `8 x! h, l% X& v* @  h
  854. /* Returns:                                                                                                                                *// i, Y( M4 s. e7 W: W" |. u5 r
  855. /*                Nothing                                                                                                                        */5 @6 T, x6 p% h5 i( g
  856. /************************************************************************/
    . G8 t3 Y' C- q8 b# q' A* u+ t+ c
  857. void Chip_Erase()
    4 j6 v* z* [- l0 s
  858. {                                                % h" J8 Y' x" V6 V9 s
  859.         CE_Low();                                /* enable device */* D: K5 C; U% Y* c
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    9 i5 C  y8 A1 |9 s4 X$ w( l% Z6 w
  861.         CE_High();                                /* disable device */
    # c* w! d. [, t$ h; J% W6 ?/ k
  862. }: H4 y  c, j8 d8 m  d1 J6 [2 O. L

  863. 9 R3 w6 a; @3 x& b
  864. /************************************************************************/
    . |1 R! `( x3 T2 j) x; y
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    ; g4 y" c  h( i7 ~  Q
  866. /*                                                                                                                                                */
      q: S. ]/ i8 h6 g( A
  867. /* This procedure Sector Erases the Chip.                                                                */
    1 ^- l. x3 H6 w0 ^
  868. /*                                                                                                                                                */
    & e. O2 E2 e4 S" k0 p% C% R/ w
  869. /* Input:                                                                                                                                */
    4 c0 T: u) ~- ?+ F7 x- i
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    " P* D4 j$ t; N& G- O5 x- \
  871. /*                                                                                                                                                */
    + M% a9 @6 c4 w3 h6 V
  872. /* Returns:                                                                                                                                */; g% @$ v' f: r! d" U( S" q
  873. /*                Nothing                                                                                                                        */
    2 O# e. T7 ]4 n; G3 @! f
  874. /************************************************************************/; z5 E- ]5 R5 b0 s+ z# z* C. f% s
  875. void Sector_Erase(unsigned long Dst)- v( T. t( n& v6 T# z
  876. {8 a: O4 {0 \. Q2 d/ m2 V

  877. ; z( @" n& }0 C( y9 ^" Z( c

  878. . z' b  `& P; D( P6 @* d! Z
  879.         CE_Low();                                        /* enable device */# W) g2 I$ R' E4 _" g! \. G* I. ~
  880.         Send_Byte(0x20);                        /* send Sector Erase command */8 V& Q4 [5 p5 j) g$ n7 S( H) Y
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ) J! J+ S2 d" x) g4 S$ q, a
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    0 m8 W. a7 L. K* S) E$ k
  883.         Send_Byte(Dst & 0xFF);3 ]( @: s8 a6 H8 s1 }) n
  884.         CE_High();                                        /* disable device */. T! P" T% c1 @$ _
  885. }        + i5 S: M" m% v6 z: c9 _+ h( L+ b* J
  886. 9 i  p# T/ @1 j% f. x% t
  887. /************************************************************************/$ c4 Z! y# n  o2 h" U1 I# ^$ \
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */" }5 N+ m; G' x# |  n, ?% n' g
  889. /*                                                                                                                                                */
    6 ]9 E- m0 R5 [/ o8 ]8 J* V
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */8 [* x+ s" K8 M8 [5 Y
  891. /*                                                                                                                                                */
    / M) t4 j9 {+ G0 n7 d* E
  892. /* Input:                                                                                                                                */
    3 [9 |. f1 t5 P7 }: u
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    5 C: U6 e$ K# ~5 V: r9 J$ ~1 Y
  894. /*                                                                                                                                                */2 d8 @( Y, U: A5 }3 o; V
  895. /* Returns:                                                                                                                                */7 \. |/ y  j( X! H+ d$ p, h
  896. /*                Nothing                                                                                                                        */: U- B: J3 [6 [8 |. K
  897. /************************************************************************/8 K' S- |& A4 X$ Q" t* {9 R& d
  898. void Block_Erase_32K(unsigned long Dst)
    1 ~5 ?7 G) P* p/ X. ^
  899. {
    & O6 j( h: D$ Z" j$ \/ N
  900.         CE_Low();                                        /* enable device */
    , r! [2 q" P# v# E
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */% \2 ]" _3 y  H7 \. U- K" r& D
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ) G7 C( V3 q4 _
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - i' t* t9 m' o$ G8 u+ l) y
  904.         Send_Byte(Dst & 0xFF);5 s6 p$ ^$ ?4 \1 Q8 w0 d
  905.         CE_High();                                        /* disable device */
    3 r- d4 ~+ s9 j# t
  906. }
    9 L) [0 P- d9 J: a+ c

  907. 4 e6 }% k+ ~# J* P3 `, m
  908. /************************************************************************// g$ P6 ~: P# z  z& E8 z2 x$ i1 R
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */4 S& N2 A- t. T( z$ j* z
  910. /*                                                                                                                                                */
      M# U( T6 q5 r5 n& i
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */- Z4 I# Q. l. X. o; u# U
  912. /*                                                                                                                                                */5 H1 C$ Q; o" J, g; k
  913. /* Input:                                                                                                                                *// }' `; B* T; N; }4 e# i
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */( N! N) Y+ H/ \1 L/ u
  915. /*                                                                                                                                                */
    9 b( {/ r4 h* r& K
  916. /* Returns:                                                                                                                                */
    ) r" d3 H' @3 ~0 `8 `
  917. /*                Nothing                                                                                                                        */
    ' j* F& Y+ t- K6 c
  918. /************************************************************************/$ F' S0 L) p2 q& k" {, f
  919. void Block_Erase_64K(unsigned long Dst)
    / v0 E. W; Y/ t% _- ~' }0 S
  920. {
    2 B3 ?) j9 W* I  U0 I
  921.         CE_Low();                                        /* enable device */6 V6 K$ E) W* W
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    7 \" R2 b) h7 S" {. j
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    0 G- l& u2 k$ E) S1 y
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));2 C; N0 r3 M. Z, p/ Z( r2 n2 H8 g
  925.         Send_Byte(Dst & 0xFF);
    / R* C7 E7 F$ W% R: N+ p
  926.         CE_High();                                        /* disable device */
    ( o9 q/ X9 g* |5 q& ^/ `
  927. }! J. x6 a3 ^  v: e3 t' R& q

  928. 8 Z: z# R' b. G3 B3 C& B' J
  929. /************************************************************************/
    $ _" D0 z* z' d7 H1 G
  930. /* PROCEDURE: Wait_Busy                                                                                                        */. t6 o, A) F/ Y! T
  931. /*                                                                                                                                                */
    $ ~" c: I/ J5 ?1 X( I+ R1 Y
  932. /* This procedure waits until device is no longer busy (can be used by        */3 B7 ]% I) b0 c
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    ! u* u5 f( V* d4 |
  934. /*                                                                                                                                                */
    1 f9 A, U6 u2 O$ W: w, k
  935. /* Input:                                                                                                                                */
    4 \9 L  J4 [# F& [% u) Q  a
  936. /*                None                                                                                                                        */4 h/ U- M; _9 v8 _4 u- y! K9 t6 q* L
  937. /*                                                                                                                                                */
    . s; S3 Z! t7 z) r5 x
  938. /* Returns:                                                                                                                                */
    4 @, }( F- v  a' C/ d
  939. /*                Nothing                                                                                                                        */
    + `# F: W* T. b. C0 Y
  940. /************************************************************************/; t1 c8 Z) F  U
  941. void Wait_Busy()% J5 I" [/ d- y& I2 u* ]4 J
  942. {
    8 B' H' w% g2 o9 A
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    7 a6 s& T& s; e4 T
  944.                 Read_Status_Register();
    0 a1 O9 u* [4 a$ v; P6 M
  945. }
    9 U8 `, b, G$ m" Z/ X1 q4 q
  946. ) p# ]. m  Z! Q: D, @
  947. /************************************************************************/
    4 y& }% E. a# V% z* \" z
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    + H! V: u% t8 r: B! [2 u. ?1 g
  949. /*                                                                                                                                                */" ]7 A8 x. B* P/ E! _; Z& J9 A
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    7 \, `. Q: z9 F( S$ ^$ q5 h* Y  u5 J  v+ ~
  951. /*                                                                                                                                                */2 ^; D3 C* z9 r% w* w" y3 e8 A8 I( Z7 k* W
  952. /* Input:                                                                                                                                */
    2 |6 |/ o- l# s9 b& @/ v4 b; E
  953. /*                None                                                                                                                        */
      x: O" B  M" D+ q0 X6 \! ?( G
  954. /*                                                                                                                                                *// a- R. N) j/ k: S0 s& X) U
  955. /* Returns:                                                                                                                                *// _) [% l1 Q. M: p, h  _
  956. /*                Nothing                                                                                                                        */6 b& m: b  a* v* r
  957. /************************************************************************/
    8 @  N& N. K9 P; u2 R6 S5 r
  958. void Wait_Busy_AAI()- D2 {6 r! Q& v6 k3 j
  959. {
    & N  ^- ^/ k2 \0 S' m5 L% \- j7 J
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    3 V1 Q1 K/ {6 m
  961.                 Read_Status_Register();) Y. X- C$ \: \6 s- @9 L+ u  m
  962. }( \2 r7 G; Z0 Q7 Q1 u

  963. ( M5 t$ Z  _6 B* p& Q
  964. /************************************************************************/9 l7 [5 ~# P8 k7 F
  965. /* PROCEDURE: WREN_Check                                                                                                */1 Y% y1 j/ t7 O9 h7 ~/ V( Z
  966. /*                                                                                                                                                */
    8 k) n1 d4 k6 T/ y
  967. /* This procedure checks to see if WEL bit set before program/erase.        */4 q- G$ y: V  }+ y4 ~
  968. /*                                                                                                                                                */
    6 V/ y4 k& N! K2 D
  969. /* Input:                                                                                                                                */
    & x5 `* [$ f& I, [- q
  970. /*                None                                                                                                                        */* T: R# ]2 `  |5 E8 T' r8 t4 d, e
  971. /*                                                                                                                                                */: S3 N+ S- a" `2 I6 f0 o7 V: P
  972. /* Returns:                                                                                                                                */- ^1 y1 g8 ~& k( H
  973. /*                Nothing                                                                                                                        */
    ' L! [& _0 `6 m/ l; Q0 v
  974. /************************************************************************/+ d+ o4 p) C/ {0 }% h
  975. void WREN_Check()1 t7 X, k6 c- s) S, w6 E. x
  976. {3 x* ]$ m5 F% K" i, u  a7 t4 Y
  977.         unsigned char byte;2 ^5 L" O; a, h# R
  978.         byte = Read_Status_Register();        /* read the status register */0 M6 a; e8 |, L+ \
  979.         if (byte != 0x02)                /* verify that WEL bit is set */% w' u) P& j  `# E) l
  980.         {( `1 L+ i* b! ^7 P' Y1 e
  981.                 while(1)4 ^! n0 a4 ~" \5 Y  I: t2 D
  982.                         /* add source code or statements for this file */+ c: m5 _( g/ }7 ]6 s
  983.                         /* to compile                                  */- P0 C- `, Y& r! v0 m# R
  984.                         /* i.e. option: insert a display to view error on LED? */' o* m8 F# h. d& v' @
  985.                  * H3 G) y- e1 S6 D* ]
  986.         }7 t- D: w2 {+ _* T/ [
  987. }( ?& R- I' \- ]( U
  988. " s9 q( r0 ~! x
  989. /************************************************************************/
    + b; s3 h6 a' G6 J/ Z# o
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    0 A* o+ j% J' B2 K6 t, D: `9 Q) y
  991. /*                                                                                                                                                */
    # Y5 s! Q: E8 Y  l3 v
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    9 q& `9 ^  f1 t8 H" ~
  993. /*                                                                                                                                                */
    6 y- s0 _* o, [0 M) w
  994. /* Input:                                                                                                                                */
    ( G* n! _, C+ E, |2 \
  995. /*                None                                                                                                                        */6 g+ m8 F! N1 b
  996. /*                                                                                                                                                */
      p: C. l6 {. R* t
  997. /* Returns:                                                                                                                                */5 K6 q) y/ ^- g" Z: q, `/ H
  998. /*                Nothing                                                                                                                        */
    ; q: K7 N6 T% ?
  999. /************************************************************************/
    . u+ [  K# S" W2 j0 I% w+ v& U- P
  1000. void WREN_AAI_Check()) c6 F) M9 G& J! Y0 ^" _
  1001. {% |1 Z  o0 x0 |9 `3 d; C
  1002.         unsigned char byte;, X. T# x& I- l( d5 q
  1003.         byte = Read_Status_Register();        /* read the status register */
    / {' L8 ?; T6 ^
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    - T! d/ Q! d, \
  1005.         {) C/ t4 Z8 I- k- ~; K
  1006.                 while(1)                ! y9 U' b8 t% M' C; L
  1007.                         /* add source code or statements for this file *// ]4 \4 h/ N% c+ {4 }, {9 J. i  T
  1008.                         /* to compile                                  */& J; l3 ?: |# K! i, K
  1009.                         /* i.e. option: insert a display to view error on LED? */& h$ E. N% o8 u+ L0 j; F1 X
  1010. ) \8 D/ Q* F7 |1 b5 X# Y- K: c
  1011.         }
    6 r0 N$ c4 y! h7 O. r4 Y
  1012. }
    / N0 J& q; W8 b0 Y7 [1 \1 ?! s$ i) f
  1013. 9 U% T: x$ l3 D! W
  1014. /************************************************************************/0 t' T- P+ w4 a
  1015. /* PROCEDURE: Verify                                                                                                        */
    ' T! R; \! f2 U1 N
  1016. /*                                                                                                                                                */* X  n9 k/ t* {, u, W" N, z0 H
  1017. /* This procedure checks to see if the correct byte has be read.                */# J9 x5 {7 M9 z5 K) {1 g2 |
  1018. /*                                                                                                                                                */
    / M) x6 e. a( s5 _: c9 ?- S0 @
  1019. /* Input:                                                                                                                                */
    - q9 t* C8 n$ C3 J  |- B* B; j6 H
  1020. /*                byte:                byte read                                                                                        */
    8 D/ G. k: I" {
  1021. /*                cor_byte:        correct_byte that should be read                                        */$ c% K4 b7 M& g- a$ }
  1022. /*                                                                                                                                                */
    : C/ p$ }3 H% f( r5 G$ ?
  1023. /* Returns:                                                                                                                                *// m2 F0 f/ o$ i9 q: I
  1024. /*                Nothing                                                                                                                        */9 N' r0 J' S# U
  1025. /************************************************************************/9 Y0 g6 S" m7 T5 ]$ U/ ~* F
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    9 \4 b9 c) R' u3 W" w. H: Y
  1027. {
    2 L8 f, _4 Y8 v1 E  w
  1028.         if (byte != cor_byte)2 P* p$ p9 T2 u: ]/ w$ u
  1029.         {
    5 r# ^( ~& n7 M+ \" q2 y: Q( R
  1030.                 while(1). T9 Y! ?7 K  h* O9 J0 g  R) ]
  1031.                         /* add source code or statement for this file */( k" r+ H; w8 Z* P+ O9 g
  1032.                         /* to compile                                  */
    " D# E' S4 a  [/ _8 V3 F' E% I
  1033.                         /* i.e. option: insert a display to view error on LED? */& Z+ x5 p# S5 t3 Z6 H# f2 W" e
  1034.                
    6 U: g( f4 o6 Z7 C
  1035.         }
    , m5 u2 X  ~7 ~5 X3 r8 {* |" k0 N
  1036. }
    ( X( @  _" Y" z2 `4 s4 q3 j
  1037. + S" A, r' v  e6 c& t% @
  1038. + b, D4 y' P$ |4 S2 P* }
  1039. int main()7 l& n$ f8 v! G  q& I* ?  |
  1040. {
    , v' G7 P! p1 ~/ T' w7 |

  1041. ! n+ O' D9 A5 z, o5 S
  1042. return 0;
    9 M% Q2 v0 o8 C9 ?
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:" |  B. N; U$ K" }% B9 _- ^6 v
   main()
3 J# z$ \# A/ ?* H" s  ]0 x   里面怎么是空的呢?
) X; A0 E$ B* Y$ P0 r7 r   发一份给我吧- e1 y9 w0 E8 u& P, O3 T/ o6 Y
mail:luyijun2005@hotmail.com
8 h( y  [2 n9 j5 i& |6 a" g6 s, 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才能执行。
9 x) U4 b7 M8 g+ _$ R7 |2 |( d
+ k# c2 Z8 T: T% S5 f" D+ ~2 h, }5 k: Z[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
5 Q* F, G9 z1 P2 oEC的代码在哪跑,你看DS的说明,每个EC都不同的。
3 Z3 A/ \1 e4 b* C3 SOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
. k# D0 x6 C; N0 }5 Z上面几个问题是你没看任何东西而白问。  D  S7 D( }0 z; {1 t3 k
) B1 h! X# c" L/ @! U3 s, y
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
  A- }# u' p7 I6 m7 c9 l- V4 W0 |/ Q, G4 B+ X8 S0 \
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
7 ~$ v/ @& p) y& p$ Y
$ X) e  f% ?5 c9 i) {, G* W; t关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
/ e3 H2 O. R7 e! {. Y, [$ B8 a  q0 W' g5 H: I/ d; R$ v4 e7 a' l) S3 ]9 O- }  z
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...: p5 P6 g, j6 z$ D3 L) y% k$ J
+ z+ b1 ]! k- h1 e0 i9 w
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样5 W. D  D4 w$ m1 M) D1 n4 ^' g8 K
似乎要把SPI能support 到最大,这EC chip应该有好卖点
2 N8 C* P+ V8 `/ X: zBIOS功能要不要强大,也就决定了SPI Flach的大小, R4 c5 E9 i+ k$ ]9 q6 @: I
我是这么想的~让OEM去决定要挂多大!
! E0 i2 Q% ?9 |) u2 r, e如果我司有BIOS工程师就好了~哈
0 ^9 l3 y1 `  A4 [& uWPCE775应该算很新的东西,来看它支持到多大?
/ h- X: ~6 U& i$ ]  G7 a( J4 t9 N( V' y: Z) X7 d; d$ h" l1 |
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
, h( y2 q. p9 w其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
, N' m7 R; y6 X/ \) |& C
" D% u; \2 O( K这份driver收下~希望以后有用到- V, Y( g. E1 f8 X* A
谢谢bini大大
& J. J5 }! ]' O; r7 |  l; n8 ]0 U7 o2 i. F8 h9 }. B8 R% n0 B# }# y+ ~
很新很新的新手,如有错误请指正 (准备看第二家的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()
/ B. d' O( ~/ x{" |+ b# T) u* @: U! M4 Y" ~
        unsigned char temp = 0;
  P$ n, b9 ?7 b- m        CE_Low();
) a2 v/ b1 K& u0 ]. i    while (temp == 0x00)        /* waste time until not busy */
' n' s( n9 _0 O! K) n) b! ~/ y                temp = SO;: y1 Q( V4 l$ W; X7 u, Z0 l
        CE_High();9 a+ c  ~8 F. a- _4 E' C4 o
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)/ f0 h+ G6 L! F" c& |
{
; z6 }0 E; f# p0 n8 {' U        % V7 V3 K4 P+ X
        unsigned char i = 0;7 _" M$ R* m$ Y4 z/ F2 U
        for (i = 0; i < 8; i++)
+ ^+ ^( S& k/ o) S" g        {0 M+ J- S8 e. n) {% t
                1 N( L# e2 `+ j& H7 x- h2 F2 w
                if ((out & 0x80) == 0x80)        /* check if MSB is high */3 Q  r% ^% z$ J  N( N
                        SI = 1;
& |8 }- ?3 G! _  v/ j, f5 P5 F( e                else
' l6 t! s5 @; i                        SI = 0;                                /* if not, set to low */
& m: n+ ]' i% V+ d! D. L8 g 问              SCK = 1;                                /* toggle clock high */2 C0 z& p2 o! G0 e, t
   题            out = (out << 1);                /* shift 1 place for next bit */9 S2 \) B  B) D; B4 X% |
                SCK = 0;                                /* toggle clock low */9 H% }% I5 K' J* }; K
        }
! ]+ A* p" n  b! m% X7 r1 C( @}
- \! V) |, X$ m/ e$ G 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-6-4 10:29 , Processed in 0.299163 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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