找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54919|回复: 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
    5 c. a- b2 m! {7 t/ b

  2. # P9 J$ j/ b0 z6 q/ U
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory3 R3 ~! }% w. R+ G# i

  4. 0 y& Q, Z* M. k' e+ C( R6 I; x  d
  5. November 4th, 2005, Rev. 1.02 V4 {4 l. T! q
  6. ( ]8 p" r! R& s3 t/ u2 |
  7. ABOUT THE SOFTWARE3 ?+ q* C% B3 d( B- ^# b
  8. This application note provides software driver examples for SST25VF080B,+ N" i& l. F! v
  9. Serial Flash. Extensive comments are included in each routine to describe
    ) v% E& {9 m& }5 A
  10. the function of each routine.  The interface coding uses polling method : y! [1 A$ z4 M% ^. ?
  11. rather than the SPI protocol to interface with these serial devices.  The  k' g, `7 `" L2 z
  12. functions are differentiated below in terms of the communication protocols, j/ r  O, q) `' s) y4 L; v
  13. (uses Mode 0) and specific device operation instructions. This code has been
    6 w% K2 p2 ]  Q: e+ z
  14. designed to compile using the Keil compiler.2 y& Z. M0 Y: t# i# T
  15. : }( M4 |* f5 d+ }' e; I

  16. / V! P; M8 \8 i8 G5 H( _% J; Q
  17. ABOUT THE SST25VF080B0 J( i0 g* c* \5 X$ ^0 B
  18. " A+ W) P3 i+ [/ q; d& }$ _5 X
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    ' }. G. v5 o) `2 z# @8 G$ Z% Y
  20. conjunction with this application note for a complete understanding ' d# A* m0 ^) V2 p
  21. of the device.4 K3 H, }- y( z) Q/ t
  22. : g2 |0 x& C4 ^/ S# v
  23. * x3 I. R; T4 i- t
  24. Device Communication Protocol(pinout related) functions:
    8 \9 x% M/ S8 a
  25. 6 z! e5 x" g4 L  C# I# X$ p
  26. Functions                                    Function8 @+ W7 v& ]: m+ [" l2 E' n4 R
  27. ------------------------------------------------------------------& X9 j* `* A9 h& o& @
  28. init                                        Initializes clock to set up mode 0.
    4 d# `" r0 ?8 U3 J$ g- f& d
  29. Send_Byte                                Sends one byte using SI pin to send and # X1 U) r- e+ W& Z4 q. [
  30.                                                 shift out 1-bit per clock rising edge! s" ~) d/ n* n
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    " T( a" p6 W6 |" m5 @6 h
  32.                                                 in 1-bit per clock falling edge, i+ Z: E# B! C% r
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming& E* Q8 v* O% Z5 l# t8 a# R" [: s
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high! ^) W5 n. O) q" w5 l
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    : x2 e3 P) _8 g. L3 x
  36. Hold_Low                                Clears Hold pin to make serial flash hold+ q! I8 o- [6 F9 }( M' R
  37. Unhold                                        Unholds the serial flash
    & V0 `% j- y! C) f, J, |
  38. WP_Low                                        Clears WP pin to make serial flash write protected+ ?; M! n5 s1 t1 `
  39. UnWP                                        Disables write protection pin
    9 e$ B5 g) @, e( F& W3 r8 [9 q

  40. / T4 w$ H9 M+ d
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code' p3 u8 p  P) E8 Q
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    3 g7 _3 ^5 b6 b8 r
  43. software which should reflect your hardware interfaced.          , O! @$ N, n6 v0 ]& J

  44. ! M" h; K; K' U/ D$ a

  45. 2 _. o3 [9 G0 \
  46. Device Operation Instruction functions:5 F7 E5 D# K" K' }1 I
  47. 0 G+ b' Q: F, a! E. u. u( [4 y
  48. Functions                                    Function, R! d: m' G# [" {. Q" U
  49. ------------------------------------------------------------------% a1 D2 e& H1 [8 w2 ]
  50. Read_Status_Register        Reads the status register of the serial flash
    ' i- c  v3 l) r5 g9 l, t0 a& Q
  51. EWSR                                        Enables the Write Status Register1 l( f  ~( S1 S/ h. }
  52. WRSR                                        Performs a write to the status register# ?1 A% a9 J, H6 J' F
  53. WREN                                        Write enables the serial flash
    9 t# V7 u4 V# m( [) m/ U
  54. WRDI                                        Write disables the serial flash, S# I; N" V! }
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    " R* F# p3 o8 u3 Z+ T  Y
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
      U' ^( O0 M" @5 G. [
  57. Read_ID                                        Reads the manufacturer ID and device ID7 U9 m- f* {" s
  58. Jedec_ID_Read                        Reads the Jedec ID
    , ?0 z; O, [: `( r
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    4 T# n* A* a$ A( B
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    / ?9 L3 ]  @8 C
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)5 j3 u2 h4 L8 f- {
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    ) @: `; D5 M5 J; Z
  63. Byte_Program                        Program one byte to the serial flash1 e* u" n4 F) t. b" B# w+ t  ?
  64. Auto_Add_IncA                        Initial Auto Address Increment process" H+ f' a2 _! B$ H
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation6 V' ~4 Z9 Y+ W1 g
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY: e& R/ L( ~7 w' D( D1 g3 u' K
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY# e* k# U: A# j. j4 V
  68. Chip_Erase                                Erases entire serial flash% \7 y) S- n' [
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash5 v  d. z6 _0 W1 K
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash( [' e) m, U) k; t" Y5 k! f
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    . g  V4 |1 Y  y; X7 f+ ^# N' [- C
  72. Wait_Busy                                Polls status register until busy bit is low
    5 ?" ?% ^: a' L4 i2 @1 w  S
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming6 @" D5 K4 Q$ h( j
  74. WREN_Check                                Checks to see if WEL is set
    3 E' m4 g9 R( S- d( L6 B9 y6 R
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set' x9 J1 m1 t. s

  76. , C: N$ N7 f* v7 y8 L0 O. M

  77. 1 v, j* r! c* T; g  M
  78. 5 e9 @3 R  R# k1 Y/ f( g3 \0 u
  79.                                                                      
    ( V  j. j: }& m5 Z- d0 Z/ |
  80. "C" LANGUAGE DRIVERS
    6 o. d1 L+ D+ E7 V3 e: D/ o

  81. ' \( d+ X. J( R# ]2 p$ b* `
  82. /********************************************************************/. b& F% |" Z! W6 |" S- ~+ l4 |' q
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    3 |3 l1 q: @& K# E" F4 v3 u8 J- a
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */4 S! f4 x# {# J$ F
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */3 S% d5 n/ d  a& b" e# E6 C/ H
  86. /*                                                                  */
    9 i% Z8 }7 J% U- s: w3 D7 [% C
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    - U6 V( A1 P2 V
  88. /*                                                                  */
    ( f' O$ ^: K! L& l* d
  89. /*                                                                                                                                        *// K( ]0 w9 o, V" n1 O' V& T* ?
  90. /********************************************************************/
    % w+ i! \0 T5 f2 N

  91. : b: F8 P0 u4 C
  92. #include <stdio.h>
    0 ^/ X2 r/ f0 R5 F4 [& J
  93. #include <stdlib.h>' W3 _1 H, r$ }

  94. 6 ?7 x! U& s) v# q1 i/ X
  95. /* Function Prototypes */* x+ K2 }( ?  y, [8 I4 j, {+ m. l- G

  96. * I, ^+ B9 a) i5 Y9 {1 K
  97. void init();& x5 t) d( x  w# L
  98. void Send_Byte(unsigned char out);9 h( l5 A9 D- h3 }' w
  99. unsigned char Get_Byte();! b1 C4 O: Z& [
  100. void Poll_SO();7 `" W; a! h1 H( P
  101. void CE_High();
    . \9 c+ Z" n( @4 `( t9 g6 S
  102. void CE_Low();
    & S  {3 X; h/ E! O
  103. void Hold_Low();$ L1 f6 E1 J( O7 `. S
  104. void Unhold();
    1 e+ z9 f: G" y
  105. void WP_Low();( n6 v- D3 }5 x, J& q- Q. _
  106. void UnWP();3 x  ~3 e8 e2 C* }7 g1 k
  107. unsigned char Read_Status_Register();$ B" ^) i- j( w+ h+ Z( |
  108. void EWSR();
    7 `1 Q) r4 v. ?$ j* A" Z
  109. void WRSR(byte);
      ]3 e$ C7 |6 W
  110. void WREN();7 l* [- Z' T- [' |' r6 H% M7 G
  111. void WRDI();/ `7 y1 G* h* a9 E$ [# n1 Z0 j
  112. void EBSY();
    ) ~' Z4 Y6 p, }7 k
  113. void DBSY();3 p5 O$ f' q5 u. ~: e1 o
  114. unsigned char Read_ID(ID_addr);  K1 _. a2 m. Z1 w0 a) T
  115. unsigned long Jedec_ID_Read(); 9 |! j4 U. }  F& r' a9 N
  116. unsigned char Read(unsigned long Dst);6 v$ s9 F' Q" H, a3 T0 P  L
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    5 N8 t' K* e$ r! G. E' f/ h0 w5 J
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    * f2 X8 M/ P! B1 y) t
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    ) l) K8 Y  l" ~/ d( U6 @
  120. void Byte_Program(unsigned long Dst, unsigned char byte);0 S5 e" n7 ]8 f* t  `) E/ K0 j' L
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    - ]& v, N/ ]' l7 A% Y
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    0 T0 Z% }3 j0 A- l4 [/ X) a
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    3 [1 M- L2 H! X
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);+ O5 w& G& h3 e' ], `$ z
  125. void Chip_Erase();* U, D! T$ ~+ s. v. c) w* u+ ]
  126. void Sector_Erase(unsigned long Dst);
    5 I) s( G" H7 \1 {1 t! F) W0 v; Z3 k
  127. void Block_Erase_32K(unsigned long Dst);
    # h- F9 \* P: {# y$ G. e7 ]3 X
  128. void Block_Erase_64K(unsigned long Dst);
    6 l/ f5 a; a& _( E
  129. void Wait_Busy();9 m" Y" {" L$ u3 N
  130. void Wait_Busy_AAI();
    7 q+ F/ Z: r. ?1 R
  131. void WREN_Check();# ]* v1 Z" Q# F# H* }
  132. void WREN_AAI_Check();
    : B1 w5 z  Q( G. q( C

  133. 9 m) q4 u( U6 U9 X/ ^" c# V
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    ) C% x$ e7 c5 g% u. I7 p

  135. 6 a" K8 B/ q% s/ ~2 i% r1 f
  136. unsigned char idata upper_128[128];                /* global array to store read data */7 R' W; o/ ?( _* _8 X, L) O0 Y  y
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    # T8 c) f1 b) S
  138. 2 [9 S0 y7 ?# p: e" p3 |
  139. /************************************************************************/
    ) k3 M/ e7 \3 m) e9 b6 I8 l
  140. /* PROCEDURE: init                                                                                                                */
    , r! w- Z1 n) {  z
  141. /*                                                                                                                                                */1 `4 f8 X& i+ w3 f6 [$ I
  142. /* This procedure initializes the SCK to low. Must be called prior to         */$ R( `! Q9 V- N1 ~) P# f: [
  143. /* setting up mode 0.                                                                                                        */
    ) r% q1 T8 _3 B4 d( L
  144. /*                                                                                                                                                */0 G& y4 v1 `; a5 B, V( t! P' `
  145. /* Input:                                                                                                                                */
    1 j" O1 L9 ?+ C) ]
  146. /*                None                                                                                                                        */& {7 I/ B, ], {" V3 |, ~5 H; i- S
  147. /*                                                                                                                                                */
    5 Z  r& [' `: y. s; L  t6 j
  148. /* Output:                                                                                                                                */
    ; u) \: q7 t1 A
  149. /*                SCK                                                                                                                                */
    % M" w1 s5 Z; ]# @' f
  150. /************************************************************************/9 u" d; B6 i- C* N7 k
  151. void init()7 ^% q2 K. F3 D: ~
  152. {
    : w! m4 y6 Z8 n* k2 \' t- Z
  153.         SCK = 0;        /* set clock to low initial state */
    0 o% X( Y( N7 w( ~7 F: N
  154. }( m; p/ U: _7 k3 ^  j7 R
  155. % G' l4 F2 Q6 [/ K0 @  i
  156. /************************************************************************/
    2 E# A; W+ @2 `2 J7 M
  157. /* PROCEDURE: Send_Byte                                                                                                        */9 K5 ]- t0 Y& y0 R$ l
  158. /*                                                                                                                                                */7 D% u# h" q5 i3 y2 K$ H" S- a7 n3 }
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */7 _. \! n" Z$ }! H
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    0 t0 o( ^2 P7 X9 w" l
  161. /*                                                                                                                                                */$ c% }7 j2 J. G) M
  162. /* Input:                                                                                                                                */" o! F! T3 c- A
  163. /*                out                                                                                                                                */
    * z! R/ ]  q6 `$ }) X
  164. /*                                                                                                                                                */
    $ d5 c/ b: _' f' g4 Y" L# e8 @
  165. /* Output:                                                                                                                                */# q+ _$ M8 f" g/ G
  166. /*                SI                                                                                                                                */
    0 G+ s0 ~/ B+ }1 k
  167. /************************************************************************/
    + \6 \6 _2 T( n
  168. void Send_Byte(unsigned char out)
    : C# [" k% t& V0 s3 Y. ?
  169. {
    / A) C1 Y* I' Q5 O; a" G, z: Q
  170.        
    ( o  i/ O7 X( C& K: d: J/ t2 r
  171.         unsigned char i = 0;! B% h1 @' J2 Y- t( V
  172.         for (i = 0; i < 8; i++)' h3 f1 j/ ?$ m! l
  173.         {
    * d- C. _9 `" t7 R: M/ q& z! Z
  174.                
    6 O+ ?0 C9 G: }2 w
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */
    ' e6 K- Q5 k8 i* L6 l
  176.                         SI = 1;
    " ~, c7 r9 s4 X# h( I
  177.                 else
    - z# H2 f7 n% \! ^
  178.                         SI = 0;                                /* if not, set to low */: {, h% @: [# B! D5 p9 k
  179.                 SCK = 1;                                /* toggle clock high */
    * r/ k# L& ]* b" Q, S
  180.                 out = (out << 1);                /* shift 1 place for next bit */! T# w( J1 O' W  V! @. n
  181.                 SCK = 0;                                /* toggle clock low */4 h, p7 Z0 a# [2 s# F6 \# Z
  182.         }; t9 L/ f. t% a3 ^( v; c
  183. }6 p5 W$ G8 C! o9 X

  184. 2 {& D9 l, {; W' Z5 [6 U' i" w+ I: z: |
  185. /************************************************************************/
    5 A7 y/ q8 Q( X% ]/ j5 H' t
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    4 i) _5 e5 G& Y7 @+ Y' F
  187. /*                                                                                                                                                */, X/ U' i. w% q; ?  D
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */; ^5 O" k6 Q* S: ]/ B+ d
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    3 F; [  Y) t2 I. {# K: p9 r. i
  190. /*                                                                                                                                                */
    $ s- q6 A! j& d3 u5 s
  191. /* Input:                                                                                                                                */, z, Z& i6 X: `/ @1 ~
  192. /*                SO                                                                                                                                */& E0 U" a# H% J5 h' C8 X
  193. /*                                                                                                                                                */) Y, _$ V! N8 H, F% O* j
  194. /* Output:                                                                                                                                */' h* d9 v0 {( p0 V: j
  195. /*                None                                                                                                                        */
    $ f9 h' j$ p2 E6 u- H7 f+ Z" [" U% s
  196. /************************************************************************/: K# L" X2 I( Y2 j6 M3 \4 B
  197. unsigned char Get_Byte()( H5 [  Z! h4 d  ^' }' ]+ i
  198. {( ?# V3 E2 s3 r& s2 o
  199.         unsigned char i = 0, in = 0, temp = 0;6 U. k- I" F2 r$ f8 ?
  200.         for (i = 0; i < 8; i++)
    2 B+ @1 a- X$ p2 N: P2 i8 Q+ y& X
  201.         {
    5 {1 H5 W- q7 d; Q$ C. o
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    % @# {) O- c5 I7 Y, R
  203.                 temp = SO;                        /* save input */  `/ p+ r! J: ^2 Z. Q; E6 R2 n) I7 q
  204.                 SCK = 1;                        /* toggle clock high */. [7 e) y* Y5 l
  205.                 if (temp == 1)                        /* check to see if bit is high */) y0 H' ?; j: z2 t# L  V
  206.                         in = in | 0x01;                /* if high, make bit high */1 H, S1 O- H. {4 L3 g' ]: I

  207. 7 H& M1 I! |. l& x
  208.                 SCK = 0;                        /* toggle clock low */
    7 A( u" j7 E2 V
  209. # r' W6 e6 D" G/ I/ E( p
  210.         }$ R% [% \. P1 [' [
  211.         return in;
    / Q- T& Y9 c# C; M8 }
  212. }7 O. @5 y2 ]( Y- e1 x% o' Z

  213. 0 r  _& k& g# J7 B# D3 i
  214. /************************************************************************/' E, I1 i8 p" I0 {: O+ o2 W
  215. /* PROCEDURE: Poll_SO                                                                                                        */9 H) l) l) K( u; i* R+ z% V, X/ j- c
  216. /*                                                                                                                                                */# U; T% O8 Q# Z1 L
  217. /* This procedure polls for the SO line during AAI programming                  */
    0 \2 X* }4 z4 M6 K
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/( k+ I6 K9 s' q7 G! Y
  219. /* is completed                                                                                                                        */# n* m& Z4 g. i8 m  K, S
  220. /*                                                                                                                                                */- h2 {+ m5 o2 _* o* {9 k" R
  221. /* Input:                                                                                                                                */
    4 M3 K9 v  {# y; k
  222. /*                SO                                                                                                                                */
    6 [, d; z+ C2 y, _7 a5 B+ `. i
  223. /*                                                                                                                                                */
    + U0 e! I1 y5 |$ N; ]
  224. /* Output:                                                                                                                                *// X' `' i1 ^* R+ b
  225. /*                None                                                                                                                        */
    8 M/ F" d; ]) b
  226. /************************************************************************/& g' n( D% T: i3 j7 q) m5 Z" d
  227. void Poll_SO()" W3 ], A1 d5 r2 c
  228. {
    5 F) Y! K! W) W* l% k
  229.         unsigned char temp = 0;
    ' ]0 W4 \. k3 i: G7 W& T. r
  230.         CE_Low();. w; }0 F  H7 B6 |5 r) n
  231.     while (temp == 0x00)        /* waste time until not busy */+ s) p2 H! K) L* m
  232.                 temp = SO;
    - w" c: o0 B% E3 E! _
  233.         CE_High();
    7 j( C" V; D. t  G7 |- x+ I
  234. }. u; F4 o! C  F* j

  235. - p2 f' \" {8 b
  236. /************************************************************************/$ d7 Y, @0 u" E" {& C
  237. /* PROCEDURE: CE_High                                                                                                        */
    5 d5 a/ a, x' ~/ p" f: j, [! D' I
  238. /*                                                                                                                                                */
    , b$ A( S+ q* l* |* g0 `
  239. /* This procedure set CE = High.                                                                                */
    / g* k6 y- a% n6 q; x4 O
  240. /*                                                                                                                                                */
    ! Z  l1 X" D( ?2 c6 e
  241. /* Input:                                                                                                                                */
    : p! T( {' I7 [5 E" w; v! k; H
  242. /*                None                                                                                                                        */. W' k2 m; q8 }% z+ \
  243. /*                                                                                                                                                */" ]& _# U, w, e) N
  244. /* Output:                                                                                                                                */
    0 }( U8 F2 ^1 S2 Z+ C& b
  245. /*                CE                                                                                                                                */: f. [. u" u/ n1 D
  246. /*                                                                                                                                                */( Y; ~% f, V7 n% V- k7 y+ F
  247. /************************************************************************// g  D. M, n2 C$ \7 {8 `
  248. void CE_High() # N. Z0 A* n9 s  f7 q) b, q( |6 H
  249. {2 B' Z6 r3 v( E0 T1 K: ~
  250.         CE = 1;                                /* set CE high */, u; c" k, ]# v9 U
  251. }
    2 a/ O; B, @# W+ E* J# H+ n

  252. $ o$ p- n; S# q
  253. /************************************************************************/' p  C) w: v; P, Q& |7 c- W
  254. /* PROCEDURE: CE_Low                                                                                                        */
    : F2 j  }( f: N% D
  255. /*                                                                                                                                                */
    ) q; p. S) C4 m- q8 N" k+ U* X* t
  256. /* This procedure drives the CE of the device to low.                                          */4 ]0 E4 g$ m; M  f+ E, u7 {$ h7 f' o
  257. /*                                                                                                                                                */
    * b2 k9 t7 I5 A4 ]6 F0 u
  258. /* Input:                                                                                                                                */, e! e8 F7 ~9 m! l
  259. /*                None                                                                                                                        *// v" f  n! m9 T, X
  260. /*                                                                                                                                                */7 n1 i- S2 _* T8 U6 N& ~
  261. /* Output:                                                                                                                                */
    2 w3 o% ^$ N+ Y) s; V
  262. /*                CE                                                                                                                                */
    8 ~. S8 j6 J4 q# t
  263. /*                                                                                                                                                */1 I  t! Z% R' l5 h
  264. /************************************************************************/9 k6 D+ h6 f2 g+ K  A
  265. void CE_Low()
    - t) ^6 s- M! F  s
  266. {        ( D& r: `8 }; ?1 x
  267.         CE = 0;                                /* clear CE low */3 w' d- b* r3 e6 T
  268. }
    9 M! L* a) ]6 {, f8 A9 t% [

  269. : G7 d/ f, l* ~$ m( N, m# Z
  270. /************************************************************************/1 r/ |0 k' r( \! ]
  271. /* PROCEDURE: Hold()                                                                                                        */
    1 Y! t& K" M% a$ h1 O' v2 b5 h' m
  272. /*                                                                                                                                                */
    8 r$ V7 f, v  I  y8 a+ E1 N! j
  273. /* This procedure clears the Hold pin to low.                                                        */- S5 a* \5 s( Z/ X
  274. /*                                                                                                                                                */
    ) l6 f$ U1 G1 N* b% n3 F: `
  275. /* Input:                                                                                                                                */0 [' l: I) ?1 w9 b$ b2 d4 b
  276. /*                None                                                                                                                        */
    . R' M3 x5 ]" g4 d+ H# e+ J
  277. /*                                                                                                                                                */
    % U4 V) c! {7 ?1 Y0 T2 g# U" K
  278. /* Output:                                                                                                                                */" N8 L" o9 b- b$ ^
  279. /*                Hold                                                                                                                        */
    5 D, k& v1 p6 z  d4 C( N, P; Y
  280. /************************************************************************/% c( K$ x- t' b3 w
  281. void Hold_Low()
    # c/ b# Y% X4 F
  282. {
      I( g. g" b7 y  @; E+ ^/ F/ o: B
  283.         Hold = 0;                        /* clear Hold pin */. I# o; S& P* Z: t/ N
  284. }
    7 N  c* _( w8 P4 ?; w1 n5 [, x

  285. 3 ]  a$ X+ l) C
  286. /************************************************************************/! z, q$ U/ Y. s" b5 `! N: w1 m+ o
  287. /* PROCEDURE: Unhold()                                                                                                        */
    0 d+ L% D- j2 C1 s5 v
  288. /*                                                                                                                                                */
    # F5 C2 l: N* o5 Y0 U/ x" ]
  289. /* This procedure sets the Hold pin to high.                                                        */" B8 G' N6 m. o
  290. /*                                                                                                                                                */8 \1 T7 G0 N: {8 q$ k( U6 L4 k
  291. /* Input:                                                                                                                                */! c$ }6 e, c9 S8 u- h
  292. /*                None                                                                                                                        */
    ; {3 {& S  X# |1 @3 I6 N
  293. /*                                                                                                                                                */
    ( H) n/ r7 {  H$ G) v# ?$ ^4 o
  294. /* Output:                                                                                                                                */
    4 \2 M6 d1 e6 x. p5 H4 h, }/ Z. h
  295. /*                Hold                                                                                                                        */
    ! D1 O7 g! Z' |1 L$ \
  296. /************************************************************************/% f+ o; q8 N- A. j2 F/ }& Y
  297. void Unhold()
    4 }4 u+ x" H" I6 C; Y0 X6 B
  298. {
    5 P" o1 T( J6 U5 h9 n
  299.         Hold = 1;                        /* set Hold pin */* T2 t# o% n- W" j( P+ j8 B
  300. }. W' O! b+ G  N( j) _# m9 p" |- D

  301. . \7 F: f% d( \( ^# y2 }
  302. /************************************************************************/
    6 p9 v8 N( T5 c' r9 z8 O/ ]/ F! h. O  Q
  303. /* PROCEDURE: WP()                                                                                                                */
      j* ]& M: d% L' {% \
  304. /*                                                                                                                                                */' t2 ~/ R2 m4 a* m$ G
  305. /* This procedure clears the WP pin to low.                                                                */
    ! c8 [+ u  I4 d3 q6 a7 y: Q2 {, I4 n* Q
  306. /*                                                                                                                                                */
    ; L2 G6 v# r: o
  307. /* Input:                                                                                                                                */1 n& J# `5 U) ?
  308. /*                None                                                                                                                        */, H, W/ ~& u$ h" ]2 O  |$ _
  309. /*                                                                                                                                                */
    2 ^$ L- T9 i6 S- o, b
  310. /* Output:                                                                                                                                */
    : V6 A7 h: t+ D" W9 b
  311. /*                WP                                                                                                                                */
    $ u! N; O: E  f) y
  312. /************************************************************************/
    2 a. o1 ]! e6 |
  313. void WP_Low()" n  @# e+ C' {1 O3 y
  314. {$ b2 |. p$ W) w
  315.         WP = 0;                                /* clear WP pin */4 ]( X/ x, J. f: h3 p) `
  316. }6 _/ T, l3 B3 H4 V; u
  317. ' Y0 Y; [" V. ]3 a' \( v. E5 A
  318. /************************************************************************/& S+ _4 x& {1 ]4 b1 Y
  319. /* PROCEDURE: UnWP()                                                                                                        */
    7 p# z$ Y! b# }  s8 n) g0 F' R6 _
  320. /*                                                                                                                                                */" O5 `8 T! f( r% [" u# C6 [- h
  321. /* This procedure sets the WP pin to high.                                                                */
    ' v$ C' n2 k/ j) M& |, [
  322. /*                                                                                                                                                */* l2 \$ J4 d: {' |6 G% j9 `- r
  323. /* Input:                                                                                                                                */
    / N, A: h. w: k0 N! D* d- D4 ]
  324. /*                None                                                                                                                        *// a& G9 S0 p9 t9 f/ k3 l% |
  325. /*                                                                                                                                                */
    8 w7 }  b5 z( J2 \
  326. /* Output:                                                                                                                                *// z: y# Q, ^3 ]& b7 L+ x
  327. /*                WP                                                                                                                                */
    9 j4 u+ l) e8 j, U# R* O
  328. /************************************************************************/8 K" U. I' e  t3 i) E: V* w
  329. void UnWP()
    / b1 l2 I& _- O& W
  330. {
    8 p& {7 t3 n; S5 }* D
  331.         WP = 1;                                /* set WP pin */
    ! t* A8 s: B- \, K4 @2 ?0 h
  332. }
    9 n5 n$ s# d0 k- p6 ^& N% C2 A4 U
  333. - T: @5 }7 W) X+ N7 F  X. C
  334. /************************************************************************/
    ! e' w) u; s* s; q' n$ u; B
  335. /* PROCEDURE: Read_Status_Register                                                                                */1 ]: {- d. ^0 S
  336. /*                                                                                                                                                */
    ! g9 R$ U$ P- E3 ]- {& n- N' [
  337. /* This procedure read the status register and returns the byte.                */8 h( ^; x- u, b5 ^* h  b$ S. O( u
  338. /*                                                                                                                                                */9 q) r; [, H: _$ F9 x, R
  339. /* Input:                                                                                                                                */9 J) I$ t  ^& n3 I5 H$ C
  340. /*                None                                                                                                                        */- y% W0 I! O) K3 ^7 V
  341. /*                                                                                                                                                */
    ( V; @0 W5 h; f& E3 }2 a( \
  342. /* Returns:                                                                                                                                */( {: @; L' F9 g7 d/ g6 \8 d
  343. /*                byte                                                                                                                        */
    / W8 q* h3 R' g' U& v
  344. /************************************************************************/
    1 G5 a6 J, G0 c" y$ ~: }& z) v
  345. unsigned char Read_Status_Register()( y+ {7 B( }/ F1 r( c- z0 y( r
  346. {5 K0 ?5 s8 O; g) j
  347.         unsigned char byte = 0;
    ' e; \# }! M+ c$ @' Q" R, D
  348.         CE_Low();                                /* enable device */" T) n" g7 y. _0 S# ^; |# `
  349.         Send_Byte(0x05);                /* send RDSR command */
    " Z6 r! [3 b. W. j+ W* G% ]
  350.         byte = Get_Byte();                /* receive byte */5 [0 j/ M' h# ~8 E! W7 z8 F
  351.         CE_High();                                /* disable device */
    1 b7 M8 [5 a2 M$ t% L4 {
  352.         return byte;
    - s+ A+ e" R5 q3 p/ n
  353. }
    : ?+ t: u% L) ^
  354. # T4 j8 \/ r& G; G1 E
  355. /************************************************************************/; b4 w  n! J5 T( U$ D
  356. /* PROCEDURE: EWSR                                                                                                                */
    ; W4 H: T8 o% j) k2 u0 I
  357. /*                                                                                                                                                */
    . D, Y; m* p/ F; }1 A
  358. /* This procedure Enables Write Status Register.                                                  */
    ; G, j% z) j8 K
  359. /*                                                                                                                                                */
    $ L5 f& \3 g/ B" V
  360. /* Input:                                                                                                                                */# f6 M3 K5 E$ x" C( q) O
  361. /*                None                                                                                                                        */
    ; s4 L- M3 X0 L
  362. /*                                                                                                                                                */
    2 F3 `1 H/ N- D6 K. H! N. N
  363. /* Returns:                                                                                                                                */
    3 J( h: t7 z1 f6 I4 M6 D! m) D
  364. /*                Nothing                                                                                                                        */2 `0 w: x+ ?/ M! ]0 I3 \, d9 R$ s
  365. /************************************************************************/
    . i2 x; b, f+ y3 ]
  366. void EWSR()9 E% f9 H! ]" h4 T1 i
  367. {9 a- o; A& v6 x4 r# ^2 I3 h
  368.         CE_Low();                                /* enable device */) S! [  y0 e5 l4 ^  z3 T7 B& U9 Q, w
  369.         Send_Byte(0x50);                /* enable writing to the status register */( Q9 ?3 Y3 p8 N5 l4 g
  370.         CE_High();                                /* disable device */* t6 s" \# Q, t2 S% U
  371. }* D  ^& t( C$ A
  372. # f, [: h4 o$ \" l
  373. /************************************************************************/4 o7 O* H0 S1 E1 i8 w# T( f
  374. /* PROCEDURE: WRSR                                                                                                                */
    3 K$ c+ ~- c+ ^/ ~" z0 S9 a
  375. /*                                                                                                                                                */
    1 q4 ?. Y3 a: R& m+ A  A( K
  376. /* This procedure writes a byte to the Status Register.                                        */# A2 w/ a% @2 k( Z8 x0 i1 f. ?" |+ T* N4 _
  377. /*                                                                                                                                                */. a- X  @; u9 N7 _8 Q
  378. /* Input:                                                                                                                                */
    3 ]; {" }+ K0 a5 w) n' v0 `
  379. /*                byte                                                                                                                        */7 j2 z% I5 c: [7 r2 F7 `- B
  380. /*                                                                                                                                                */
    7 v! C* _7 t& a1 u9 w6 U- q
  381. /* Returns:                                                                                                                                */9 T6 U8 u1 Z# _1 t0 f8 U% E1 D
  382. /*                Nothing                                                                                                                        */
    ; @3 {  I, [+ s
  383. /************************************************************************/
    / U5 O. N6 J* }6 a' l0 i
  384. void WRSR(byte)+ ?' @: D7 \, D; U) `
  385. {' _3 K- E& D5 E  i
  386.         CE_Low();                                /* enable device */5 C0 n* e$ k8 V; U8 w" N( p
  387.         Send_Byte(0x01);                /* select write to status register */7 D" v/ `: [7 j3 G" K
  388.         Send_Byte(byte);                /* data that will change the status of BPx ; [1 S0 \! r' d: t/ e) N+ ^
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */4 S; v& t+ \& M: C8 V, s' J% q. y
  390.         CE_High();                                /* disable the device */3 `: |. T& G. R1 _
  391. }
    ) ^0 g, G9 e+ K( b

  392. ' }% J8 y6 O6 Y- |9 z! |
  393. /************************************************************************/
    ! r: f3 l& W- a, L8 G8 o
  394. /* PROCEDURE: WREN                                                                                                                */) k* @# ?( \  P8 U* z. w
  395. /*                                                                                                                                                */, g- h1 _& ~5 |& g
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    . D9 E; Z+ G# m7 A
  397. /* to Enables Write Status Register.                                                                        */
    # H; X( h! z2 w
  398. /*                                                                                                                                                */: G4 y" A; a2 N
  399. /* Input:                                                                                                                                */
    ; f( ?4 o; t% }; D$ K( y
  400. /*                None                                                                                                                        */
    8 M; V0 z8 r1 u; l3 Z2 x4 z4 n3 n
  401. /*                                                                                                                                                */
    , i5 G0 B( O4 v: W% h8 T6 L( f
  402. /* Returns:                                                                                                                                */8 H8 {4 R+ p) `; u3 n
  403. /*                Nothing                                                                                                                        */
      H5 [) Z% o9 H0 C( Q
  404. /************************************************************************/
    # J( P2 o$ }$ Y3 ]
  405. void WREN()
    # |9 y4 r  K3 V3 X  B: M& S5 R  D
  406. {* Z# e; w" M9 @, A2 m& b
  407.         CE_Low();                                /* enable device */
    - c! X3 g9 E' b. x% O: ?' h2 \
  408.         Send_Byte(0x06);                /* send WREN command */
    5 R0 i) x4 n: B" |2 r, _
  409.         CE_High();                                /* disable device */* F" C' d& r2 I/ x
  410. }
    ; F3 D0 A( e* o) x$ |

  411. ( m& z2 Y, R) t' N, |! D2 D
  412. /************************************************************************/" z5 H% J3 U, l( o; d- A
  413. /* PROCEDURE: WRDI                                                                                                                */3 l; ?6 R3 m; i4 e; ?
  414. /*                                                                                                                                                */
    ) Z* \- |9 }; r$ Q7 H' h; j
  415. /* This procedure disables the Write Enable Latch.                                                */7 t: m7 i2 B4 ?6 H# N+ P
  416. /*                                                                                                                                                */
    ; z* f( C; Z. w3 V, t0 n3 W2 |9 K1 c
  417. /* Input:                                                                                                                                */3 \) t, {4 }: Q* o9 M5 s" o, j& a* g$ g
  418. /*                None                                                                                                                        */; \$ W. _- ]; v/ ~
  419. /*                                                                                                                                                */
    * E% T: n  W' J3 r- ~; v. p
  420. /* Returns:                                                                                                                                */
    / U. R* l4 C; X. q
  421. /*                Nothing                                                                                                                        */
    4 {' x/ Q- b0 L
  422. /************************************************************************/
    % @* N; T: `% d% U' ~3 Q% h
  423. void WRDI()
    5 J1 G, M5 f' j7 W2 |
  424. {9 Z+ @5 z/ t" D9 `! E
  425.         CE_Low();                                /* enable device */$ W% n6 {' d, P) m. G, A# g# b) @
  426.         Send_Byte(0x04);                /* send WRDI command */( z# v: @4 \7 M% j& s
  427.         CE_High();                                /* disable device */
      L% n1 A) m6 W% ]/ K7 I' s
  428. }
    / D  G3 Q  V2 n5 z8 O/ c) s& D# x$ H

  429. 5 t+ ^6 E: t/ X4 ]) B- F
  430. /************************************************************************/) O5 q# J& v1 b: x- R+ p0 i7 _
  431. /* PROCEDURE: EBSY                                                                                                                */1 a5 Y- D, C( }8 F
  432. /*                                                                                                                                                */: A: R* U9 T0 c" I3 Q* d
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */. o1 c; @- @" Y" Q, ]
  434. /* programming.                                                                                                                        */, {3 a' g" y; b  K* P/ F4 _# L
  435. /*                                                                                                                                                */
    + \  I* J* e3 ^2 L4 \: B
  436. /* Input:                                                                                                                                */5 {: R# f4 k  C/ K. v) W
  437. /*                None                                                                                                                        */
    # f% _  C! k& Z& {6 N: ]
  438. /*                                                                                                                                                */
    9 e/ }, I7 E; v( ~, m9 }
  439. /* Returns:                                                                                                                                */& d( `; y# Y, f$ G  V& q
  440. /*                Nothing                                                                                                                        */
    : _: w7 K/ f6 p+ i9 @
  441. /************************************************************************/( ]. f9 B4 V3 R/ Z0 N
  442. void EBSY()$ N5 L+ K, [7 ~" o+ f# J
  443. {
    ( Q) p) F/ Z- [* {" A0 i2 B
  444.         CE_Low();                                /* enable device */
    . k0 u9 i- q4 d% @5 e0 A2 C6 k- R1 p
  445.         Send_Byte(0x70);                /* send EBSY command */
    ; ^& c7 A. p6 W2 F
  446.         CE_High();                                /* disable device */5 d" [  a6 f2 e. c- b
  447. }
    7 R5 p' n7 p) M2 e

  448. * [) G, p( d. @7 y
  449. /************************************************************************/, H6 c& p5 [! U( H2 A4 A5 i4 J7 c
  450. /* PROCEDURE: DBSY                                                                                                                */4 J* x# p/ D( [0 ]$ k% p; Z6 _
  451. /*                                                                                                                                                */
    8 q* @; q9 W* e  J$ q. k" Y+ n
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    5 `+ z3 i* i( c
  453. /* programming.                                                                                                                        */
    4 \/ ?* a4 P2 U
  454. /*                                                                                                                                                */5 P3 O1 L( ~" z- \0 r
  455. /* Input:                                                                                                                                */; P4 F5 p# f) }
  456. /*                None                                                                                                                        */
    ! \  f# b" c, h5 ]
  457. /*                                                                                                                                                */' {. ]0 }3 n6 B7 C0 V+ `  i
  458. /* Returns:                                                                                                                                */
    3 O! M$ T% B/ m7 H( |' X8 }  L8 E
  459. /*                Nothing                                                                                                                        */; v' {: I6 V! K. G( {  `
  460. /************************************************************************/
    " W1 u) {; }* E: j1 @4 z4 X8 e
  461. void DBSY()6 |$ R  O! h- j  ?, M$ b& h% q
  462. {; l1 R, k7 W5 I7 X: l
  463.         CE_Low();                                /* enable device */9 w7 M  c( G/ t% F6 r
  464.         Send_Byte(0x80);                /* send DBSY command */
    % o; @8 f! ?' B5 F2 N
  465.         CE_High();                                /* disable device */
    ' H" g$ }' W$ e2 R/ B4 Q
  466. }
    ( ^7 H7 s7 g1 `. `8 r8 W
  467. 5 U+ m* D- }# b" Y; G) T7 f
  468. /************************************************************************/6 {$ j8 C" J' Y1 |: G
  469. /* PROCEDURE: Read_ID                                                                                                        */  h) H' J, V3 a+ n( ~! ?5 U( t1 @6 R( X
  470. /*                                                                                                                                                */, T. l5 ^/ }* f0 j! G7 \. C* N
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    8 {% d! m, T9 I9 y' E$ A
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    & Y# v# B( B0 {& ~
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    6 L' l1 G9 m7 O: h7 ]8 I
  474. /* whether the device outputs manufacturer's ID first, or device ID         */' X# o( j& F8 T6 v# g) j  f
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    $ B7 \4 g/ M- G6 {8 E  S: j
  476. /* variable byte.                                                                                                                */) L/ e# A0 v7 H' x
  477. /*                                                                                                                                                */
    1 {9 I: P; @: B. p& o
  478. /* Input:                                                                                                                                */: T* |* M( P0 r2 B, \
  479. /*                ID_addr                                                                                                                        */
    8 z% S; d( {$ c( C
  480. /*                                                                                                                                                */
    ; s# l6 k( D4 B+ H; A$ i" n
  481. /* Returns:                                                                                                                                */) f+ V$ Q# \. _$ q' O6 c
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    : _' [7 m$ t5 A5 q
  483. /*                                                                                                                                                */
    ' K/ A3 ?) |1 c( d( Z; C$ i
  484. /************************************************************************/
    # C" |, m, U* P( J: _
  485. unsigned char Read_ID(ID_addr)5 C9 @7 v6 n7 F, K' c: G& D& N) ~
  486. {
    : P' i( |' r8 V, E
  487.         unsigned char byte;
      ~$ j. B$ J7 g; G  E% w" o
  488.         CE_Low();                                /* enable device */- e7 @8 X7 C) a6 W1 W+ [) M' _
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */% O' ~( P& d. ^
  490.     Send_Byte(0x00);                /* send address */
    + R3 t. W& x3 ^& [, |
  491.         Send_Byte(0x00);                /* send address */
    - R/ Z2 X& ]& Q) T
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    ! `" `/ Y/ x% o: G# a; _
  493.         byte = Get_Byte();                /* receive byte */
    , w* ~7 ^( v3 Q
  494.         CE_High();                                /* disable device */
    - ^5 D$ g8 }% B) R
  495.         return byte;1 O2 T) A; R5 R
  496. }
    * j: p" n4 Y$ P' J7 s

  497. + k" e% j3 e* J2 B; {( m
  498. /************************************************************************/+ x' a; S) C- H; N+ K
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */- l( Y2 V3 I$ g3 }
  500. /*                                                                                                                                                */; k; _' f! F# q2 h# Q8 [# ^# x
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */0 H) ]" F, `$ n, R# F! P8 I- e0 Q
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */- S; ^/ s$ z4 {8 R. L! \
  503. /* Please see the product datasheet for details.                                                  */; I) J% f3 ?6 y1 Z. P& F
  504. /*                                                                                                                                                */4 F! Z. H, f  n% f( o9 z
  505. /* Input:                                                                                                                                */
    ( g6 v- _$ {3 T
  506. /*                None                                                                                                                        */
    1 B+ G% i( m  C! r6 V6 c# V
  507. /*                                                                                                                                                */7 l9 ~/ x! e8 t
  508. /* Returns:                                                                                                                                */" @2 \9 ?, a8 h! Q/ n1 j
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */: L2 h0 |/ w+ ~8 ^+ @' b
  510. /*                 and Device ID (8Eh)                                                                                        */% A& [' U. ^0 w: q+ J. S
  511. /*                                                                                                                                                */
    6 d) g9 \( e; m. N
  512. /************************************************************************/
    0 B: L: ^. e4 f7 q! V4 d
  513. unsigned long Jedec_ID_Read()
    % l- N0 P$ ~* v
  514. {
    & j& _* c. L6 y/ m
  515.         unsigned long temp;
    * t/ X& O% h; ?& c4 N0 @2 {7 U
  516.        
    , T$ U! W" Y2 ~' K
  517.         temp = 0;
    ! u/ W) r/ s$ Y& |$ u; N
  518. " j. S7 H9 a1 J+ T
  519.         CE_Low();                                        /* enable device */
    - w- ^! p, e& X0 \8 w0 k- C3 G4 u
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    9 ^; A4 ~: l/ O% ^- U3 J( u. P. V
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    : P: X& W  s6 F' M: m
  522.         temp = (temp | Get_Byte()) << 8;        & u" O. c$ Y% m6 [1 K0 p
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E *// T9 m1 A0 i2 \( `" u7 e! w
  524.         CE_High();                                                        /* disable device */
    " y* E' z! Z/ r' ]* y+ X4 g  b! ?

  525. 9 ~+ L  e0 @  |- H$ z% U: ~
  526.         return temp;' G. M- I3 J5 w* L- n+ l
  527. }# p& U; }& \, t

  528. & V" z7 b: h1 L
  529. /************************************************************************/: h+ {: i5 {5 Y
  530. /* PROCEDURE:        Read                                                                                                        */
    0 l* I0 k( s1 y/ C* V: n
  531. /*                                                                                                                                                */                ( P; l0 s; R" @& ]4 ]$ r* t3 c
  532. /* This procedure reads one address of the device.  It will return the         */  J( P& t5 }' j0 N* I6 v3 a( V5 _
  533. /* byte read in variable byte.                                                                                        */
    1 F0 b2 N5 F) G# q- `! ~
  534. /*                                                                                                                                                */9 i4 o  {  _( X+ \2 D  r7 I
  535. /*                                                                                                                                                */
    0 i4 i# y* x; i  ^$ A
  536. /*                                                                                                                                                */0 y+ i9 [: o" \5 H$ W+ g: Y
  537. /* Input:                                                                                                                                */
    # E5 r  K' t* A, U
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    2 [: @9 ]7 C; c: H+ Q) @
  539. /*                                                                                                                                      */
    * |9 R3 X6 \5 N1 A& @
  540. /*                                                                                                                                                */
    : @3 M# E. o$ ~' D6 u
  541. /* Returns:                                                                                                                                */
    ) f1 r1 r9 A5 ^* e" s* ?$ c
  542. /*                byte                                                                                                                        */0 I* a) O. U5 W4 C& q$ A/ o
  543. /*                                                                                                                                                */3 H6 Y- p! X+ V# i4 c# o; S8 f$ B8 ^; [
  544. /************************************************************************/
    1 f: D5 Z9 A0 j
  545. unsigned char Read(unsigned long Dst)
    2 J  |) s. b6 Q4 R
  546. {
    / u. M" h; E, D) h; @8 |5 X
  547.         unsigned char byte = 0;        ; D; T* I# L8 I0 U: m* @( E

  548. : \% \" P( |) ^0 o6 I
  549.         CE_Low();                                /* enable device */, I7 u3 u! [& s7 f3 X7 R
  550.         Send_Byte(0x03);                 /* read command */, H$ ^* ?* L1 H2 ?4 {( K* z
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */8 P4 G- ^% Z# p- ?  ]
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    0 N5 s% A+ B" B, e' h
  553.         Send_Byte(Dst & 0xFF);
    * A0 _7 W/ D8 {. H' b
  554.         byte = Get_Byte();
    . V0 ]+ g; ?1 ]/ f1 V
  555.         CE_High();                                /* disable device */
    * U. L3 M6 y8 B6 H2 R: c) i
  556.         return byte;                        /* return one byte read */
    ; Z0 ~2 [4 M, e7 H! r1 @" W7 P/ U3 }9 O
  557. }8 b6 f! Z* f2 G3 J+ p( J
  558. * i- L2 M4 \. _7 m; T! U; X
  559. /************************************************************************/9 m+ v# O# f, y/ R# u
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    $ B- `; e7 h! Q. y$ S/ h
  561. /*                                                                                                                                                */               
    & N5 x& R5 w9 f+ L3 l
  562. /* This procedure reads multiple addresses of the device and stores                */) s, a) C; H* X7 O
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/" L& U5 {4 j( c% v
  564. /*                                                                                                                                                */- M5 U4 ]$ E8 u$ q. `2 v5 S8 f
  565. /* Input:                                                                                                                                */
    7 @1 o! f, J; a+ e( ^7 z
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */3 v' {, S) ]$ C9 y) p  {
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */9 Y  `) p, p) R9 M
  568. /*                                                                                                                                                *// C  Q6 ^& [0 D; O% V! _
  569. /* Returns:                                                                                                                                */8 J8 B  A8 d; M# g7 I1 A
  570. /*                Nothing                                                                                                                        */) W  o* S* o  {
  571. /*                                                                                                                                                */
    * e: g2 q/ P. X/ n5 y
  572. /************************************************************************/
    ; l( q9 F& [3 F
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes); k; H+ V3 f- n# F% E
  574. {" H; I! W- o+ C# h3 W. s
  575.         unsigned long i = 0;2 U3 o# q( _; s4 R5 p
  576.         CE_Low();                                        /* enable device */
    ! Q% ]% |6 r- y2 M5 }( K
  577.         Send_Byte(0x03);                         /* read command */
    : c. T$ O# i5 T7 v. N5 ]& z! @
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    & p1 X6 Y" M1 R- K: j' T
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 c3 V1 \# X  B) g  `: Z. r& }4 ^
  580.         Send_Byte(Dst & 0xFF);( |1 X1 B# b% J, X; c+ o
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */1 m$ i# _1 L' A( f
  582.         {
    8 Q4 _8 q3 k0 {# V2 J
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    2 T- [4 _) y* F* |, e0 r
  584.         }* `+ D0 y/ p) P3 l: o
  585.         CE_High();                                        /* disable device */% g+ d! L/ Z0 |$ I9 `6 P9 R
  586. * n$ z, V( B1 D9 E3 L* d) k+ m
  587. }& |- O* _% Z; A8 u  e, B+ F

  588. 8 o! V* M8 K5 E
  589. /************************************************************************/; B+ U7 s6 y) X$ j
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    # `+ |& A# b2 E% L) K' F" \" g
  591. /*                                                                                                                                                */                : H( a, x  t$ W* P6 G" w" O
  592. /* This procedure reads one address of the device.  It will return the         */
    * f6 a' C  c& G9 b
  593. /* byte read in variable byte.                                                                                        */  J1 S: r( t4 ~2 u0 K
  594. /*                                                                                                                                                */9 t- g) {3 V9 ~; k. [) ]
  595. /*                                                                                                                                                */
    ) E; D/ e6 G3 ~4 s" o% Z
  596. /*                                                                                                                                                */  W9 W% {3 E  f" I) D7 u3 O
  597. /* Input:                                                                                                                                */# h  O! X7 W0 m
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */7 j  E7 E2 Q; ^) }
  599. /*                                                                                                                                      */
    % S$ u: K) p! O  a* t
  600. /*                                                                                                                                                */! U7 A) t9 r8 Q- ?5 n
  601. /* Returns:                                                                                                                                */
    5 _! F  c5 ^8 A* |, m, q4 [4 S6 k, N
  602. /*                byte                                                                                                                        */
    ) H) t! @7 v5 ]. ^- e
  603. /*                                                                                                                                                */( T$ o/ F, ~5 ~3 G3 O( k/ @) j
  604. /************************************************************************/
    4 A1 `+ i# v: ^; G8 V
  605. unsigned char HighSpeed_Read(unsigned long Dst) # C7 @2 N  P( P' g* b! f
  606. {+ v2 \2 k! i  o
  607.         unsigned char byte = 0;       
    + m% e' W4 z' b! ~1 i* j% \4 h2 r

  608. 8 u% }& [3 B) v# l2 j4 f* y
  609.         CE_Low();                                /* enable device */; q2 u8 s: h5 s6 n1 q
  610.         Send_Byte(0x0B);                 /* read command */* l( A6 `7 t" m5 k' @* P
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */' N, L4 \0 t% c7 f/ I8 }, K$ `2 ]
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    / W  d3 f( b+ [9 |
  613.         Send_Byte(Dst & 0xFF);
    - g8 ?# m7 R8 q
  614.         Send_Byte(0xFF);                /*dummy byte*/
    . z+ o& ^' p+ [% l. f' c
  615.         byte = Get_Byte();# c* x4 e+ L- J! h9 ?
  616.         CE_High();                                /* disable device */
    6 D- F: i+ N) L, Z, p0 U* o# C
  617.         return byte;                        /* return one byte read */% B4 D6 |# E: d8 G- G! j
  618. }
    ' B7 e4 Q7 C' W9 p8 h, C

  619. - J; K/ f5 z, S9 T3 e9 [1 `! p
  620. /************************************************************************/" P8 `2 ^. }9 Q! C1 _0 {
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */* i7 V) x0 `3 x$ n' U3 h
  622. /*                                                                                                                                                */                / s' T- S# o3 K5 D- p+ T, M- Z
  623. /* This procedure reads multiple addresses of the device and stores                */
    $ i$ K4 t2 _- k6 [
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    : x* y* }0 t, E
  625. /*                                                                                                                                                */! {5 k( A7 {3 m. M6 l* T9 R
  626. /* Input:                                                                                                                                */
    ( ]! u+ F  P7 t2 b
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */2 Z8 {$ U; w( q" L* h; J4 l7 r
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    " ]& Z7 V0 H& @7 P& u3 {
  629. /*                                                                                                                                                */) b" c& W- c( W* F3 z
  630. /* Returns:                                                                                                                                */
    - }1 @5 |* |8 L! u9 g3 x  ]! \
  631. /*                Nothing                                                                                                                        */& U1 l  A* h& v9 Y+ h# G( l- B$ q
  632. /*                                                                                                                                                */6 O( x( i. G9 F5 C. q: ?1 ~* I
  633. /************************************************************************/
    * f/ q5 M' a$ _( g
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes), M* s' x2 Z; N; F- y1 t# M, j0 ?+ o5 C
  635. {
    ' A( C3 V2 c# ?1 b! x. ~( d
  636.         unsigned long i = 0;
    # s3 P- N  Q% A# \1 m
  637.         CE_Low();                                        /* enable device */
    & F8 j9 _( ?, @/ S2 G' j
  638.         Send_Byte(0x0B);                         /* read command *// H1 O  r0 x. a: I8 e
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    7 ~4 H9 m4 M9 n" C. E
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    9 E: G+ H0 H# _: `1 N' G7 A
  641.         Send_Byte(Dst & 0xFF);
    / d" p* f* q5 G; a
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    5 W( _' @! o6 j2 h7 M3 A: K7 [! I
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    3 I! p1 I1 d* k
  644.         {# Z+ c, ^- n' ~; m9 A. q4 v
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    0 l! F1 h1 S5 |8 J
  646.         }
    5 s6 j6 C6 U9 q; T7 {# X3 ?$ P7 o0 H
  647.         CE_High();                                /* disable device */- j! h: d8 G, m1 B, ?" t+ M& h
  648. }
    ) @" E9 x& m4 S# w

  649.   ]3 {/ ]& z. ?
  650. /************************************************************************/
    ( O/ I& k3 F8 m6 G2 B
  651. /* PROCEDURE:        Byte_Program                                                                                        */  c5 f1 J. W) V# x& _4 z) W
  652. /*                                                                                                                                                */
    $ r5 E& O1 O  g4 q1 y
  653. /* This procedure programs one address of the device.                                        */7 m: w& ~: j1 N3 a7 z4 o, m2 ]- J6 b1 x
  654. /* Assumption:  Address being programmed is already erased and is NOT        */. W  x% B* a$ G& k% H
  655. /* block protected.                                                                                                                */
    # ]& M' T: X, D; I' C1 @4 Y8 m
  656. /*                                                                                                                                                */
    ! z: a6 H+ c' U, W
  657. /*                                                                                                                                                */
    5 Y) W3 k6 e; p5 A
  658. /*                                                                                                                                                */0 D" P, H) i* T
  659. /* Input:                                                                                                                                */
    ) M' r* s0 U& s& m) w0 c$ P4 L
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    6 r% U1 ^+ F1 j2 h
  661. /*                byte:                byte to be programmed                                                                */; V5 h$ ?5 a5 ]& E
  662. /*                                                                                                                                      */
    / \: O' W- y3 d' W* \
  663. /*                                                                                                                                                */
    ! `$ u$ \) K* S0 N5 O4 u5 T
  664. /* Returns:                                                                                                                                */
    " B$ ^% i9 S* z0 C$ r# B6 O( I
  665. /*                Nothing                                                                                                                        */4 v; t7 w! b+ i. x& L& O# ~7 q
  666. /*                                                                                                                                                */
    1 |0 B9 e9 f6 a9 o6 j5 P2 a0 @
  667. /************************************************************************/' E* D: Z9 m: {0 B% z
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    0 l1 f) I) k/ R
  669. {
    . d+ t! K3 B$ e% M, f, u# j6 d- F
  670.         CE_Low();                                        /* enable device */. j$ t+ {. E% y( x7 Q' H
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    ! C& O- C9 M8 h9 Q$ v
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */8 Y( B( ]- |; B3 }2 a
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));# \1 Y8 H& B: K9 E0 B: @$ a
  674.         Send_Byte(Dst & 0xFF);; a2 L- Q$ _: a) C- [/ L) p& p% O/ O
  675.         Send_Byte(byte);                        /* send byte to be programmed */9 A) i2 E5 ]' y# D
  676.         CE_High();                                        /* disable device */
    5 r; F: P) a4 L% `3 V5 L
  677. }1 N) |8 I+ K; S7 [
  678. & H2 U! W( w+ U, R
  679. /************************************************************************/
    ! e& _$ |% W8 D* z6 P2 {
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */" U5 d9 `6 e; t1 z. k$ e3 W  S( f
  681. /*                                                                                                                                                */, p0 K; x1 v' K, N9 j
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/, l3 }; X" }3 ^# X# R6 M
  683. /* the device:  1st data byte will be programmed into the initial                 */! ]( t( a# e' X5 q! B4 d
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    ' m  ?% p' o( d
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */0 m6 U7 U. }+ T! n/ X
  686. /* is used to to start the AAI process.  It should be followed by                 */
    9 S+ U6 {% p, M) n+ [- m
  687. /* Auto_Add_IncB.                                                                                                                */
    2 F; `( P9 _+ @: k5 L  l0 \
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    1 _/ n/ ~8 t6 A1 h
  689. /*                                block protected.                                                                                */0 [; i" v- l1 s9 E% y- }
  690. /*                                                                                                                                                */# T7 y# H- u9 h1 E" b# p8 @3 t! Y
  691. /*                                                                                                                                                */$ d4 p* j1 ~7 l# [, p+ ]! A* D# x
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */! I: ]6 e: ~6 {3 b  |3 g8 f
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    2 t; t  @" J/ |0 P9 ?9 j/ J2 U
  694. /*         unless AAI is programming the last address or last address of                */
    * n' a1 [7 ~- ^" s5 A
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    % P6 U0 G6 R0 U; Q3 n
  696. /*                                                                                                                                                */  X8 p- `# |# Q
  697. /* Input:                                                                                                                                */5 ?7 o. z/ {) N# b5 Q  }% o
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    " q8 z: p" k9 a0 ^6 x4 Q8 |
  699. /*                byte1:                1st byte to be programmed                                                        */3 O5 l9 A; c7 {8 K, j5 p9 d6 s
  700. /*      byte1:                2nd byte to be programmed                                                        */+ X7 k1 ^& X2 M6 C
  701. /*                                                                                                                                                */' }5 ^" d& q2 r) z
  702. /* Returns:                                                                                                                                */
    , {8 d! V9 @& X# m: u
  703. /*                Nothing                                                                                                                        */
    ) e) P( R6 Z$ N1 }  Y0 G0 w' p8 ~% L/ i0 u
  704. /*                                                                                                                                                */
    . S" i: i0 N4 {
  705. /************************************************************************/$ [" D5 ]" B$ h. \5 }& u8 m
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ' H. |  {. Q8 J7 ~
  707. {
    ; O7 A$ [( {& m$ z8 a. V, f5 x9 L
  708.         CE_Low();                                        /* enable device */
    4 g* j6 \5 W& }' a
  709.         Send_Byte(0xAD);                        /* send AAI command */
      P0 N- w0 D% H( p# Z1 x+ |
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */0 j: p) d$ v- V6 @% Q# F$ @: [) K
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - z+ P& A0 D5 e! w9 c
  712.         Send_Byte(Dst & 0xFF);
    4 {9 ]. O2 ]8 ]- C) X% f2 ~- {
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        - E$ d+ N3 n8 ?6 ^( w
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */% n; n% _4 E" Z
  715.         CE_High();                                        /* disable device */
    & \) V$ w1 s& x/ w  {! ^* O4 L( G
  716. }
    % l8 C$ s- N: ~+ H/ ?* b" U

  717. 8 E' U$ _5 @9 B+ K- M
  718. /************************************************************************/3 P; h5 r/ x% n$ b( m# j3 Y; F
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    & ?; N- `, B  s3 @3 Y( d# Q
  720. /*                                                                                                                                                */: o/ f1 Q7 B& U. I2 U& O' X, ~
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/" Q$ `  Z# K4 g
  722. /* the device:  1st data byte will be programmed into the initial                 */
    1 @8 P) e# c  e3 m4 Y/ i0 k# Q3 `3 f
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */. b' Q/ R$ i" D
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */8 T( A; I  B" ]# l" @3 _8 Q
  725. /* is used after Auto_Address_IncA.                                                                                */
    + O% F1 e; e1 Y8 A4 }
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    , N& i- m0 ^! x& d  h
  727. /*                                block protected.                                                                                */" A1 q5 `1 k' ]5 G& R
  728. /*                                                                                                                                                */0 X( i9 X5 x: H: _" o4 Q
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */3 R# w* E2 ^6 M: B/ W5 w
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    4 O7 l+ Z1 l7 r( O
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    % b. B9 O: c$ |2 y$ T  G
  732. /*          to exit AAI mode unless AAI is programming the last address or                */, Q' f5 j5 ]& K0 K
  733. /*         last address of unprotected block, which automatically exits                 */
    9 D! L& ^2 P9 L. y# b$ ]
  734. /*         AAI mode.                                                                                                                        */9 x; u/ Y* O& J' c' d2 P- g
  735. /*                                                                                                                                                */8 t9 ?3 W$ J( \
  736. /* Input:                                                                                                                                */
    0 A5 z2 Z- C6 B7 D
  737. /*                                                                                                                                                */
    ; o) |1 ]: i" s! @. E# I' M4 j7 k
  738. /*                byte1:                1st byte to be programmed                                                        */
    - l9 G! D. Q' u+ o) g/ `
  739. /*                byte2:                2nd byte to be programmed                                                        */' p8 {9 T9 v) D9 r
  740. /*                                                                                                                                      */) Q; Z4 Y& |; a) H
  741. /*                                                                                                                                                */! T$ U( g, P( S
  742. /* Returns:                                                                                                                                */, J0 _' `% _9 |& A6 ~: `
  743. /*                Nothing                                                                                                                        */) S0 e, W0 M" d0 W1 ?3 ~  O7 J7 [
  744. /*                                                                                                                                                */
    " z; i& o. y" A' r  ?5 c$ w1 _" N
  745. /************************************************************************/  @' c7 ^4 L/ }! ^# }6 Z2 @/ [# M# ]
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)1 P+ e2 S) Q- ~- |4 L9 {+ c
  747. {
    . K, m4 m$ W- ?1 X1 a
  748.         CE_Low();                                        /* enable device */
      P6 D" `/ h3 j; B* H$ ~1 E
  749.         Send_Byte(0xAD);                        /* send AAI command */: e" V; P- ?' @' g
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    : V1 b1 e3 G2 l' N: f- _! M
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */& D1 \1 D% F; s0 V
  752.         CE_High();                                        /* disable device */1 V% i9 S% t7 a( e9 o2 ^
  753. }
    ! _( m- E' R( k' q

  754. & U) W. w1 R9 |2 B  s
  755. /************************************************************************/
    ) h; R3 f4 _. O8 H1 A" }
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    ) M7 x# p# g' H: J; S9 [
  757. /*                                                                                                                                                */
    7 g; z7 X  @6 U
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */9 t5 D4 K. r- `9 K+ h+ \8 v
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */- X; t8 |( ]  F5 n7 \# o& `0 S+ ~" U
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */! u6 L5 g. x' n7 _/ b/ A' S5 W
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    " p3 j) l# p2 S. o
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    2 @2 Z/ g. N* x3 l$ K7 t
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */: `% k* W- D; v5 @7 p
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    6 C: a& @9 Y% R  u" T7 v
  765. /* Assumption:  Address being programmed is already erased and is NOT        */$ c4 D, F3 ]) q
  766. /*                                block protected.                                                                                */. ]7 H7 F$ b2 }' l
  767. /*                                                                                                                                                */& K; k! p' [1 f8 Y2 W+ c
  768. /*                                                                                                                                                */+ u4 |3 l0 E) J
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */4 a5 ~4 U+ v: r$ V
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    $ K0 l5 Y+ R$ N$ f- X
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */, g" _. x% g5 E8 ]$ V
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    7 d. e+ G6 J; v3 V5 K0 k% |# L
  773. /*         last address of unprotected block, which automatically exits                 */" ]" U) V# y1 L& d0 e$ @
  774. /*         AAI mode.                                                                                                                        */& V1 @  W" c7 a) v; W
  775. /*                                                                                                                                                */
    " W" v% k' w  {3 @5 I: e5 g
  776. /* Input:                                                                                                                                */
    : f& p; s3 @1 V2 ^9 S
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */) o% l2 F6 s: \" \# n
  778. /*                byte1:                1st byte to be programmed                                                        */
    7 v5 J( k- Z) ~/ M  c" w) O
  779. /*      byte1:                2nd byte to be programmed                                                        */; ~( ]; h$ @; x
  780. /*                                                                                                                                                */" p- l; U* [0 ^; R- p+ P: c
  781. /* Returns:                                                                                                                                */* ~4 L2 E3 B: f  \1 d' Z
  782. /*                Nothing                                                                                                                        */
    ! X8 c+ H' \) c
  783. /*                                                                                                                                                */  i- k! q) k2 _$ p1 U! c; {7 z; b
  784. /************************************************************************/8 E& Y- ^( f9 }: I! @' \6 R
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    8 u# ~% p5 B6 h: a2 V
  786. {
    ( a- S1 Y, G8 o$ O, `. @
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        . q' C7 h9 L5 r  c+ d' [
  788. 2 H9 W0 _" P" b  L/ z. @
  789.         CE_Low();                                        /* enable device */
    ( c; ~# i. v. o
  790.         Send_Byte(0xAD);                        /* send AAI command */
    7 T" T7 C3 F% [! Q
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    + M0 M- T  F3 r! c& G/ U& {
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));4 Z2 _+ e0 o2 r1 K7 L% c
  793.         Send_Byte(Dst & 0xFF);
    ! k4 \( A2 K; p: D" T% |: R; ]
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        % W/ y& p; @$ p* B' d
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */# m2 j5 w0 A: n% Z  n8 K! P+ v
  796.         CE_High();                                        /* disable device */
    $ @6 a/ d% |7 @: Y5 w
  797.         7 |" V6 b+ ?4 w* p$ A
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */6 S: z4 ^1 p* R: k$ y/ E
  799. 9 r: m8 s$ W& m$ a
  800. }+ K2 D% c0 E5 ]
  801. 0 g; C8 N4 t& |' |
  802. /************************************************************************/
    6 _4 [3 |( L7 n; a1 y0 {9 x0 D" _5 u
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */! A+ y1 s' a' k
  804. /*                                                                                                                                                */! f: s0 q0 }% z! @; x' T& N" M1 `; }
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */, X9 K) X0 b3 h
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    ; J& D) @) I0 K# |$ @
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    ; B" |4 ~- O! Q* Q* Z1 p* M& \! n
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    % u1 [& j* F8 h" g* I! F% X7 E
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        *// X  t: o: G0 w' n5 e( U
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    ' j; u9 R- x6 `0 o
  811. /* used after Auto_Address_IncA.                                                                                */
    2 _8 c8 {: G) d9 ^  U3 l
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    ! _/ @8 ?7 m+ W3 G" T0 P. o! x
  813. /*                                block protected.                                                                                */
    " h5 D1 D  l2 `+ W% L' ^
  814. /*                                                                                                                                                */
    3 \1 ?- a& x# K1 u- Z
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */7 @& ]9 x. ]2 G, W
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */$ D+ }- Q! U5 {7 u/ E
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    / ?3 T7 `3 E' ?
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    ' A1 ?6 v3 _/ `- H
  819. /*         last address of unprotected block, which automatically exits                 */
      j. b* Y" p8 X1 P( b( q4 r
  820. /*         AAI mode.                                                                                                                        */
    2 e9 j* J  A. \% S1 N) n7 {
  821. /*                                                                                                                                                */
    , S( s2 N+ O( v+ n
  822. /* Input:                                                                                                                                */
    : a% p3 @6 d( r: @* |, O
  823. /*                                                                                                                                                */
    7 e$ Y: N7 E6 F
  824. /*                byte1:                1st byte to be programmed                                                        */6 G8 Q3 `! {% O# s; a
  825. /*                byte2:                2nd byte to be programmed                                                        */- T' z2 W- Z. o% k1 N  t0 Y
  826. /*                                                                                                                                      */' H: J0 ?) V  M
  827. /*                                                                                                                                                */* a5 r2 j8 b# O4 C, R6 o2 N  Q
  828. /* Returns:                                                                                                                                */" g5 B+ C6 a/ W" n
  829. /*                Nothing                                                                                                                        */
    0 }. i/ T$ a0 k) Q5 P1 Z
  830. /*                                                                                                                                                */: |3 R* M: [. [( }; t' Y. R
  831. /************************************************************************/, v7 `* V. e+ R( w  _4 l
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)" U6 Z% t2 `7 [: @) D
  833. {$ H# e  i8 x( Q8 i
  834.         CE_Low();                                /* enable device */
    1 ?0 j) d6 b1 p- z4 W& E
  835.         Send_Byte(0xAD);                /* send AAI command */5 K1 S* p0 n$ k) f3 c1 u
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
      n4 F3 v& `! q2 ]
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    : j, z4 X. q" @/ L9 X
  838.         CE_High();                                /* disable device */
      G6 U# R/ Z$ `/ \! D# A1 m4 A( @
  839. ; e6 U! n2 C2 l# D
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    % U+ \& s  p* L2 C
  841. - W5 V( N8 v, I- C- Z3 a" p
  842.         WRDI();                                 /* Exit AAI before executing DBSY */' r% w! ~' G5 V
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */. }7 [3 c/ Y+ Y; d7 ]
  844. }7 m. T5 ~$ _- c* R2 W/ |
  845. ( q$ _/ A$ }6 z( C' E8 F& l$ j2 T
  846. /************************************************************************/
    " F. C) f- v  s# i7 k/ ]
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    + D1 l- P5 b7 V7 ]+ [
  848. /*                                                                                                                                                */
    / f; d  A8 x9 [7 s& G/ `7 z! v
  849. /* This procedure erases the entire Chip.                                                                */1 ]& ]# c+ k" n# _" K$ N
  850. /*                                                                                                                                                */
    9 O% |  m( L- t& O$ T5 `: b% e
  851. /* Input:                                                                                                                                */
    6 v  s. g* t/ P# ]
  852. /*                None                                                                                                                        */, }' M2 R9 O3 ^% f
  853. /*                                                                                                                                                */
    & H" _: U* m4 `) ~, q  d3 l
  854. /* Returns:                                                                                                                                */
      h5 B5 d' x# [7 |2 O$ V7 [
  855. /*                Nothing                                                                                                                        */
    6 s& g$ }5 ~' a+ M( |; t3 c
  856. /************************************************************************/
    / ?, f6 |7 P7 m9 @6 A" ~6 `$ n
  857. void Chip_Erase()
    & p( d- q4 t0 X. E: `! O+ M
  858. {                                               
    . n) I3 [) E7 J
  859.         CE_Low();                                /* enable device */: P4 J0 V: n. O- F
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    * u* h" m2 p1 e( ^$ S* X0 W
  861.         CE_High();                                /* disable device */
    # r* K3 a8 z$ _4 S* m6 z
  862. }
    ; f) Z) |# X1 a4 i  s
  863. 4 B6 k. B/ z. y& e, g7 [
  864. /************************************************************************/& l; H. `: U& |; L# T- _
  865. /* PROCEDURE: Sector_Erase                                                                                                */
      |& }3 A0 \/ \! J3 v7 R+ e
  866. /*                                                                                                                                                */
    : ~/ H( z/ ]1 K7 q6 Y
  867. /* This procedure Sector Erases the Chip.                                                                */* B% I1 h% U4 @) k
  868. /*                                                                                                                                                */
    7 N9 X0 i8 R% y4 F+ W
  869. /* Input:                                                                                                                                */6 M) Y! Y; I4 x3 p. K
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    9 z% N6 ]6 p7 p- l+ k2 h3 d
  871. /*                                                                                                                                                */
    ( K" w9 U1 M! J. [- D' |  I0 x. P! {
  872. /* Returns:                                                                                                                                */4 M/ C% D: \0 N
  873. /*                Nothing                                                                                                                        */. a9 O" O8 R% Q6 y
  874. /************************************************************************/
    3 t1 u; \* t! J3 h/ W6 y
  875. void Sector_Erase(unsigned long Dst)
    9 ?) ~, R9 M& H; p2 m! h- ^2 B4 q
  876. {
      h* {& w! T! z4 J$ `+ T* V4 T
  877. " h% v- X  w' u, R, x9 a; i% [" C
  878. - m, c, i' V! H) q* {% \+ [
  879.         CE_Low();                                        /* enable device */
    7 N+ c' P# M: q1 O* h
  880.         Send_Byte(0x20);                        /* send Sector Erase command */) Y' w7 y: g$ ^$ _" @, r) G. T
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! a0 A  t8 g8 H1 ?/ x8 m
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
      N6 ]. e5 s9 _! D
  883.         Send_Byte(Dst & 0xFF);
    1 c0 ^4 R( V* P$ k
  884.         CE_High();                                        /* disable device */
    3 \. @) Q8 b8 a$ @4 E
  885. }       
    ! ?# @! J9 ]  N; V% g
  886. 5 W6 K3 G( |) ^0 z, Q
  887. /************************************************************************/
    2 Z2 c6 l5 H" o0 p: K
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */; V) v- h7 D3 X; N+ D% H/ G6 T5 W
  889. /*                                                                                                                                                */
    0 _" a+ d. @' B9 ~- n5 @/ N4 C
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    ' ^! A' @) A2 M' G
  891. /*                                                                                                                                                */
    1 P  A6 J) R1 U9 b$ I3 J
  892. /* Input:                                                                                                                                */
    1 M& ?2 M* N/ D+ x3 L  u, J
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */2 n+ {3 m. c; M  t
  894. /*                                                                                                                                                */( ?3 u- E9 F% g; _7 W
  895. /* Returns:                                                                                                                                */5 k/ D3 d; `( N# W/ K1 W
  896. /*                Nothing                                                                                                                        */
    3 |( i4 g. ?+ \4 g' h# m
  897. /************************************************************************/  @4 [6 y7 w8 H
  898. void Block_Erase_32K(unsigned long Dst)
    ' d, e0 A6 w" Q+ C( X
  899. {* [- {. k! H; i
  900.         CE_Low();                                        /* enable device */- E2 z* k8 H' q# M" m' k
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */6 y, n; i2 Q4 j
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */  E, Q; ^3 `' h' P% ~4 O
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));2 ]- z& @+ |* [# [) p
  904.         Send_Byte(Dst & 0xFF);9 s" {8 [2 ~0 s
  905.         CE_High();                                        /* disable device */! I. |0 B9 C0 ^3 v
  906. }
    ' d8 F8 f5 c* ]! C
  907. 8 |: \5 @; w, m) h) O4 t, \
  908. /************************************************************************/
    - u' v5 Q# p9 e' V
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */# i# e% k  y( W6 }5 E8 H
  910. /*                                                                                                                                                */
    0 o- V% i  g% r1 ^. u. R
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    0 q. w' u' o; w2 X
  912. /*                                                                                                                                                */
    0 R4 X( ]+ K: n. |$ o5 h. m9 _% A) S
  913. /* Input:                                                                                                                                */7 m! o# y7 V9 H6 N5 r1 C+ B* R9 r
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ( T$ {0 H0 E/ d- B9 i; ^1 u9 l
  915. /*                                                                                                                                                */0 |4 O" G) N5 H* j6 l
  916. /* Returns:                                                                                                                                */
    . f- e/ I" C8 m4 v& Q6 E. e% ]
  917. /*                Nothing                                                                                                                        */
    6 H4 }/ v- c6 ?
  918. /************************************************************************/* c0 t: D1 l- J* S& S$ g
  919. void Block_Erase_64K(unsigned long Dst)
    7 t( [6 P1 d2 J9 V! O! [
  920. {; I) F0 |* X0 ?) _) c$ v5 P7 K
  921.         CE_Low();                                        /* enable device */
    7 X5 q, t9 I, x; h9 Q; q
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */; X8 X! i' x( G2 H' D% B- n( [
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    4 Y: K% I& [- D; p" m  j% l9 w+ k  W
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));$ P% `& V- c7 v1 n5 X
  925.         Send_Byte(Dst & 0xFF);
    $ [0 Y9 g# i" {
  926.         CE_High();                                        /* disable device */
    + L3 d1 \8 m( Q/ g# a4 U
  927. }* T: \" E5 j9 H
  928. ) b  C) t; \" |% Y' R1 }
  929. /************************************************************************/: y& z& C! M- Q
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    6 e, e; |/ H- A" X
  931. /*                                                                                                                                                */
    $ S% @! T2 P0 I! @. o( Y
  932. /* This procedure waits until device is no longer busy (can be used by        */
    , u& R6 U+ ?1 M9 d8 ~/ _! [
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */8 E* n" m* I5 ?! @
  934. /*                                                                                                                                                */8 L1 t/ V/ f% X8 j: U! J& I5 s$ d: @
  935. /* Input:                                                                                                                                */
    ! m1 q6 k' w0 f# q% v: m0 o
  936. /*                None                                                                                                                        */
    , d$ |8 [) M% R, w; P
  937. /*                                                                                                                                                */
    ; ~( R( Q7 F: Y, V, G/ z+ s
  938. /* Returns:                                                                                                                                */5 A0 Y- \1 }8 u3 a5 M! f4 W
  939. /*                Nothing                                                                                                                        */* n' F0 A5 o: D- `; e* R/ ~
  940. /************************************************************************/
    5 `9 F& K2 G/ c+ Y
  941. void Wait_Busy()
    $ n- V) p# [# D$ u
  942. {1 p) f; O/ i& r0 C+ j
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */8 x; i+ ~& f3 i6 \
  944.                 Read_Status_Register();8 t3 A& {: Q$ L& h, S& J$ H; [! z. R
  945. }- e. _! S' U5 n, T$ p

  946. 7 a" V, G1 \6 C% X' t4 D
  947. /************************************************************************/6 {+ }0 F+ X7 o
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */: j4 {: q  g; x6 A7 n3 u8 I' [2 Q
  949. /*                                                                                                                                                */
    8 |/ d9 w0 R. v1 R, l
  950. /* This procedure waits until device is no longer busy for AAI mode.        */( U1 t8 C# x5 R+ C( i9 q
  951. /*                                                                                                                                                */
    6 a7 C0 T# o# K$ b! y
  952. /* Input:                                                                                                                                */
    4 v( K2 v& Q. w+ H& ^5 H% B
  953. /*                None                                                                                                                        */
    4 g! }; {1 N* `3 W7 B$ h
  954. /*                                                                                                                                                */
    * b9 p2 g! G% R0 I9 b  ]4 \
  955. /* Returns:                                                                                                                                */
    3 Y# D  B) _- A5 m
  956. /*                Nothing                                                                                                                        */
    8 a0 H6 @. v- c8 b7 Y! B( N
  957. /************************************************************************/
    7 m$ j. I! O9 g9 o
  958. void Wait_Busy_AAI()% ?+ ]6 m, M1 B1 H7 D0 m
  959. {7 @( k- D& [( |: p0 Q: U! `
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    ( Z" |9 [- B7 }! c8 ~
  961.                 Read_Status_Register();& r- k* p4 W- d
  962. }+ @8 ]; N" b' B6 z

  963. 4 D( Z* @% S% D5 R6 p1 W
  964. /************************************************************************/
    0 v; ~; N7 C) j+ o
  965. /* PROCEDURE: WREN_Check                                                                                                */
    9 H! t! C, c) m! x8 w! m+ I$ N' ?
  966. /*                                                                                                                                                */5 c2 a9 Y3 R/ X7 |6 F
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    $ e- @  d0 J* x- |. u0 b% H
  968. /*                                                                                                                                                */& v% @. R1 d- [+ n; U. K- I
  969. /* Input:                                                                                                                                */
    & `% |+ b) Q- p& |% ^# p" p
  970. /*                None                                                                                                                        */6 f2 f5 q' Q8 f. @% Z: V* `; r
  971. /*                                                                                                                                                */
    % e/ {* \. O4 i+ e0 k# a' B$ m
  972. /* Returns:                                                                                                                                */
    3 x8 _" u! \8 R6 X2 p# N6 w
  973. /*                Nothing                                                                                                                        */
    % A9 B# u- h4 W& |7 N* D
  974. /************************************************************************/; m: [2 h% m" u- B, d
  975. void WREN_Check()
    # c8 p9 I! I% V5 {5 f3 z
  976. {
    ! T- C2 U% \- a& b  I" T# j0 D
  977.         unsigned char byte;
    ) r* j* |, I- r* V3 z; ?. i
  978.         byte = Read_Status_Register();        /* read the status register */
    6 S0 _; n6 B2 a& f5 v$ n0 P
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    & Z, E' w- O1 F$ E% y8 R
  980.         {
    7 ]* a* J) K7 ?9 ^) I2 _# F5 y
  981.                 while(1)
    3 k7 b) C( R0 A( \0 E! I
  982.                         /* add source code or statements for this file */
    , \9 k/ r- E9 b* W' _
  983.                         /* to compile                                  */  R" T  @# ?3 F/ E0 x+ T2 I
  984.                         /* i.e. option: insert a display to view error on LED? */& k; V, u7 i* \% \0 j; S
  985.                  
    ! D( I  y" _2 n, ^& g0 `
  986.         }) ~% `; ]9 h5 s0 y% g
  987. }
    $ f! E( q* v2 u) p' ~  |# O
  988. ( R: D) y. ?  A$ K" i( \
  989. /************************************************************************/
    $ Y: z9 L3 C1 V1 ^5 [2 a' |- R" |
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    * f/ |6 C* X) U1 H
  991. /*                                                                                                                                                */4 S7 h) v. _) W2 W5 u, F  ~
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    - b% a7 S2 R1 f! C* U; G
  993. /*                                                                                                                                                */
    / O! M+ f% b( q2 o7 x
  994. /* Input:                                                                                                                                */% J, z. E/ v) C" Y1 l' W
  995. /*                None                                                                                                                        */
    ! \3 {1 J5 P$ n" B/ k
  996. /*                                                                                                                                                */, R9 m5 g3 {# ^4 a2 U
  997. /* Returns:                                                                                                                                */, a( W) }$ O- K& j! P
  998. /*                Nothing                                                                                                                        */
    . ], G2 P- s+ x- |( l
  999. /************************************************************************/
    : e7 A$ Z; P8 m7 d) C0 [
  1000. void WREN_AAI_Check()
    - h2 d1 Q& a# D4 d; s& B7 g( |8 [2 T
  1001. {% C: T9 p" S. G  o1 c1 n
  1002.         unsigned char byte;
    $ D  V7 j! x. U2 a3 Z
  1003.         byte = Read_Status_Register();        /* read the status register */% i: p& n4 k- x1 g) f7 J5 m6 ~
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */3 C( g6 |" |; `6 z
  1005.         {4 `! u- i" v# I% c: C# u+ h. Q- U, O
  1006.                 while(1)                2 b; K0 S6 l& |4 r9 H
  1007.                         /* add source code or statements for this file */
    ) d( w' z% z- V: s6 l
  1008.                         /* to compile                                  */
    - S! o0 d8 a; b6 N9 V: V# ]9 P6 ~  J
  1009.                         /* i.e. option: insert a display to view error on LED? */
    2 X# P$ M* {" @% k% v7 S* ?/ e
  1010. ; {* y  B( {3 \& t
  1011.         }
    & t; _1 o  b+ b. L
  1012. }7 u$ }4 O: C5 v  x  o2 c

  1013. ( c; d/ {# M" B  S. S4 F
  1014. /************************************************************************/
    + F$ d+ }9 P4 X0 b5 i- K0 K7 U6 n
  1015. /* PROCEDURE: Verify                                                                                                        */
    , W1 i3 l% u+ J# L, T6 S( J1 l/ {
  1016. /*                                                                                                                                                */
    * s# _6 v7 t  I8 j' Q/ I( f  H
  1017. /* This procedure checks to see if the correct byte has be read.                */: d' V# ?0 w. F9 ?$ O8 p7 o. N4 d, B
  1018. /*                                                                                                                                                */- \- [7 k. k3 J* ?
  1019. /* Input:                                                                                                                                */: y2 A, @  T; M2 ~& [
  1020. /*                byte:                byte read                                                                                        */
    ( P! O- B2 S3 X0 y2 P) u
  1021. /*                cor_byte:        correct_byte that should be read                                        */. c6 }' T) h: l6 \2 b
  1022. /*                                                                                                                                                */. @0 `2 Z# R, g# j1 k
  1023. /* Returns:                                                                                                                                */
    . n/ }' r4 D( X, \' v
  1024. /*                Nothing                                                                                                                        *// M6 W) u0 B6 ^8 \7 H0 \
  1025. /************************************************************************/
    ; ~. z0 I1 B4 ?. H; `4 Q0 J& M4 r- R/ {
  1026. void Verify(unsigned char byte, unsigned char cor_byte)0 O& f5 G3 z* Q) L& J8 t7 a
  1027. {
    . H+ n9 n2 z5 g1 M$ H( d
  1028.         if (byte != cor_byte)! ]; g  D5 g$ s0 Q9 z
  1029.         {+ l& J. r0 c/ B5 w/ {6 O2 ^" V
  1030.                 while(1)
    % b9 F1 j+ {5 V0 ?% N0 a
  1031.                         /* add source code or statement for this file */
    ) `  F" a! f. K( E1 \
  1032.                         /* to compile                                  */
    ) x- c* [' I- g2 }! H& T: C
  1033.                         /* i.e. option: insert a display to view error on LED? */
    , H7 R) ^% Q/ J7 k7 g
  1034.                
    . Q' h1 b% O3 I9 K) X/ D! c* J' y
  1035.         }
    + Q& k) L6 j, B3 i4 c
  1036. }6 v. T# u% @1 g* ?9 |% h
  1037. 4 o) `+ H$ G  j+ D
  1038. + A& J! p' U7 b/ }- V) D& U& M4 Y
  1039. int main()
    7 ~. u; L! Y0 T1 A  u* u: ]: B
  1040. {  Y4 h/ b/ Y, S8 O: p$ X

  1041. 6 G0 n, v+ H. P9 y
  1042. return 0;
    ' Y5 S7 K9 p) T9 y' M
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:; m% B2 f1 S" w; i, R) x! ?' w
   main()( ]$ |7 l& n' {& Y3 t7 l. [
   里面怎么是空的呢?
1 a" }$ s5 h" F/ y/ z; s" T$ b: x   发一份给我吧( L& \: X0 y) i  s
mail:luyijun2005@hotmail.com/ m: C4 ~2 g( q. ~3 o# N
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
* B0 V# h* ?& {3 N6 F- J* c% ?$ f  n' L2 D' r5 f4 G+ [
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
  o$ b% b' \' M! wEC的代码在哪跑,你看DS的说明,每个EC都不同的。
! D3 P# n* F* j" N1 jOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?8 \/ o8 Q. q5 }7 r  V" F
上面几个问题是你没看任何东西而白问。. J+ H9 h  \, H6 {# d2 a# u
) {) H4 ~" F& m& \. s/ s2 c8 C
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

& y4 m6 q) X  m关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!6 ]: v5 X7 w7 ]% g2 i& e

9 q, c2 y: @. L3 Z- v关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
8 B6 e9 y8 G" H- ?% m' w5 B' I$ C5 u8 c' s+ ^
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...! x; m' m% a# h

- e- B) g9 L, x8 Q/ ~) t不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样2 V% K2 n$ I1 g6 n
似乎要把SPI能support 到最大,这EC chip应该有好卖点# M$ T" R- W: U; Q% F
BIOS功能要不要强大,也就决定了SPI Flach的大小
6 r3 A  S3 k  E' \我是这么想的~让OEM去决定要挂多大!0 u2 p+ |# J: }9 |3 q- H
如果我司有BIOS工程师就好了~哈
1 C6 ]1 m! e! u) ~, b$ V+ hWPCE775应该算很新的东西,来看它支持到多大?
4 r" \" y7 e5 q- v8 S" S
* q0 n- _' ]6 M  k  ?# U另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte/ p6 `' G7 S( K3 e2 {  x9 y
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
+ y6 l4 P! j4 ^
! J5 @& l: X2 l这份driver收下~希望以后有用到
: N+ N4 V3 _+ j6 V1 D) L谢谢bini大大6 y1 f- B. C! t

2 l. ^6 r, X0 a7 f很新很新的新手,如有错误请指正 (准备看第二家的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()
7 j$ y! H  W- `0 b4 Q6 W- Q{* x! n: z8 V- y3 i7 d" l7 M
        unsigned char temp = 0;
5 v6 N1 H6 U+ |1 x        CE_Low();
5 c. P+ R: X9 g/ \    while (temp == 0x00)        /* waste time until not busy */! d. S, f9 e1 }$ T! W
                temp = SO;
2 {) w' y1 I; S% l! J1 x        CE_High();
9 w5 D( D( A5 D}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)1 V4 J8 h9 }; y  a8 y
{0 b; v" Y. k+ R, j& a* f( M
        5 \: k  i# Q' j7 L3 d
        unsigned char i = 0;8 p' R2 Q/ o5 D8 \' ~$ M" m
        for (i = 0; i < 8; i++)# N5 E+ k( N, _( _6 K9 G; C% {
        {
# o/ E. o1 U! W3 J               
) n& }' T4 p% Y$ w3 j                if ((out & 0x80) == 0x80)        /* check if MSB is high */
' o+ d# o! n3 Y                        SI = 1;/ D. }( ]. f: H* O( S; F
                else
# O7 k5 V5 W% F9 M; z                        SI = 0;                                /* if not, set to low */
* U5 b- V1 [/ _+ @' y$ s 问              SCK = 1;                                /* toggle clock high */  [" T& M/ p2 x' i" {: P4 ?
   题            out = (out << 1);                /* shift 1 place for next bit */0 V0 o# r7 z, u& P( g4 C- @; e0 C
                SCK = 0;                                /* toggle clock low */
" b0 L0 F  |  j8 A9 t        }2 q8 ]0 V8 |4 J
}0 R  V, t% P8 [: h# I
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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