找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55305|回复: 13

[Software Driver]SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory

[复制链接]
发表于 2007-11-13 11:07:18 | 显示全部楼层 |阅读模式
EC挂接8Mbit SST25VF080B的话,可参考和学习,其它的SPI FLASH雷同。
  1. Software Driver/ l/ J3 a  I  b' E- N9 d) {
  2. + ?& B/ G* H( g% ~
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory- r: K" J- S/ y8 \8 T' m9 }

  4. " {0 I, p% r2 Z
  5. November 4th, 2005, Rev. 1.07 w/ E# U6 F# u2 M) I
  6. . q3 V* k$ X$ B; h( \. o% ^
  7. ABOUT THE SOFTWARE
    , u7 D6 `8 {, q7 ?6 t7 Z! c
  8. This application note provides software driver examples for SST25VF080B,! z+ z! m! T- k" _: A1 A
  9. Serial Flash. Extensive comments are included in each routine to describe
    ( b2 I- h# @& [5 `& M: c5 W
  10. the function of each routine.  The interface coding uses polling method
    0 R( d6 E! {/ h+ o0 l3 G
  11. rather than the SPI protocol to interface with these serial devices.  The
      _$ Q: ]' B2 W: c
  12. functions are differentiated below in terms of the communication protocols
    " R& T( V" M% S, k
  13. (uses Mode 0) and specific device operation instructions. This code has been 5 R4 R# q1 `& z7 ^! b( {( |, }# |5 t
  14. designed to compile using the Keil compiler.* L3 U$ x: `7 l9 N
  15. , h! ^0 F! h6 R* @
  16. - i5 u0 K- {$ q6 o
  17. ABOUT THE SST25VF080B. R: o1 c' b; E& a0 Y; Q, d$ j
  18. 4 T" k5 b& u; k
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    6 Q5 q' d! G% J' S' Q, \
  20. conjunction with this application note for a complete understanding + r" l1 i8 n  \. W
  21. of the device./ s( [& b7 q! v; p8 q2 }5 m
  22. ; b/ x  B. L: F$ O0 l( R
  23. 0 t4 A0 H/ O, n; c1 \1 \7 i
  24. Device Communication Protocol(pinout related) functions:* w1 [- u; c  v7 M) W( N
  25. 0 X$ X7 r: o* Q! J, t$ Y
  26. Functions                                    Function
    : t1 l/ U" ^3 I9 v% k$ G# K
  27. ------------------------------------------------------------------7 c7 n7 d0 K1 B
  28. init                                        Initializes clock to set up mode 0." N) r: E8 y1 F6 O; t4 J
  29. Send_Byte                                Sends one byte using SI pin to send and ' U! v3 T8 ?" x- h. C/ Q$ G
  30.                                                 shift out 1-bit per clock rising edge) b" k" K$ X! w
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    9 J: L4 J4 {* }1 z
  32.                                                 in 1-bit per clock falling edge
    2 n/ z$ I! m3 _7 q# p, u
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    2 d5 k, T# a( K4 W5 j% b
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high+ D2 i$ ?) _5 L8 B/ s) Z! E
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    7 `$ a3 Z3 B' Y) ^+ [
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    % l3 }, A* N9 [/ O& e' i& ~& }
  37. Unhold                                        Unholds the serial flash1 F8 a1 Y( Z+ `' S. W4 x+ Q9 o/ ]
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    4 m, V8 l, v! V- C( ~6 }
  39. UnWP                                        Disables write protection pin
    + T' R, H8 `8 c5 Q! w

  40. 0 [# M) ^' S; Q5 [2 l
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    5 Z9 N) E; W6 W; e( x
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    2 K( J+ D3 A2 r$ \# r1 Z
  43. software which should reflect your hardware interfaced.          
    ( p# P) i; {6 E9 a
  44. - ~# e2 f) I% j1 K) k2 T( ^
  45. % T3 S( ~' a2 |+ r. B3 n7 p
  46. Device Operation Instruction functions:% V' T9 c- t, c: m1 ~# X: k
  47. $ g. ]: \$ i" k1 ]
  48. Functions                                    Function
    ! D. t4 L4 |4 W1 l: B$ b
  49. ------------------------------------------------------------------
    ( n$ J9 G8 ^; m) f5 Z
  50. Read_Status_Register        Reads the status register of the serial flash
    ' J! |& j- i1 m- L9 K
  51. EWSR                                        Enables the Write Status Register
    0 r( o2 o! V1 H) @/ [+ B
  52. WRSR                                        Performs a write to the status register5 G# }2 d8 Z  X1 {2 u, b
  53. WREN                                        Write enables the serial flash3 @% k% `  w$ ~6 G
  54. WRDI                                        Write disables the serial flash$ K( _. p/ W; y
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    # o( N: T" g, x+ H+ |; y
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    . o3 K. X5 A; b6 V& |2 d; C
  57. Read_ID                                        Reads the manufacturer ID and device ID' t/ A  `7 ]% W* x0 z5 ]
  58. Jedec_ID_Read                        Reads the Jedec ID: \1 {( z4 J+ m- K
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    ( I: z* L* t! U- M, A9 _
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)  _: [' n- R2 e
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)0 U  E  R$ I& l) r% Z8 n
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    1 O" @# ?7 i$ S# F
  63. Byte_Program                        Program one byte to the serial flash/ Q( j, K1 I; T; r
  64. Auto_Add_IncA                        Initial Auto Address Increment process0 E4 V. ^; ~2 i+ v/ g+ L$ H
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    + L3 W$ j6 O' L
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    . @1 A7 r) N9 p3 V( M
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    8 \: x  F. C" S2 G
  68. Chip_Erase                                Erases entire serial flash- P! u' ?. ~8 N* F# T* H
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash# G+ P9 E3 s: w
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    % m! [% i6 S1 `' r. _3 @
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash) N0 E7 ~, u' F3 _
  72. Wait_Busy                                Polls status register until busy bit is low
    % L- i& u0 F& i5 _: S$ D" n& Z
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    : y. ^( m+ k5 S. T9 N$ g0 v
  74. WREN_Check                                Checks to see if WEL is set9 J% P2 X! ^( |, _
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    4 g! B$ ]5 w9 S2 g7 ~& I+ i
  76. + F+ U& O4 X! C) T& h
  77. ( Q7 m& A& o8 L0 C; Y' D
  78. 1 G' n. ]: Q8 e5 v3 S4 F6 U7 z# `
  79.                                                                      5 i; _6 E' x0 V) d  H4 _
  80. "C" LANGUAGE DRIVERS
    ! Y4 x/ z/ |4 Z8 P2 \1 W! m6 O

  81. . @- H/ V( u, a, X0 p- W3 ]
  82. /********************************************************************/6 R0 n' O! y( H  I% _) ]( n. X6 {( m
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    6 U) f& [  P8 E* o! s" P
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */7 X( G; P! @$ j) n
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    4 E" p3 C1 G5 T7 P0 i7 X4 F
  86. /*                                                                  */
    $ i( [9 B- F7 A3 X( k
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    ) k- X3 _6 l: ?9 |6 e8 ]
  88. /*                                                                  */
    ) |. U; V/ O9 f- m+ R
  89. /*                                                                                                                                        */
    + d( k+ i7 `( w7 [8 X0 e' J) d
  90. /********************************************************************/
    . {3 Z, Q' ^( r  Y3 _4 l
  91. 4 p( z/ \, Q' X% Q
  92. #include <stdio.h>3 ~6 V" S0 n, ?; m
  93. #include <stdlib.h>
    / E0 E. I+ y( p- N6 O. A

  94. , G! q' B  I" c3 K
  95. /* Function Prototypes */1 p* O3 A; f3 H: l+ W+ V6 D/ l

  96. ( r. j+ G; o' A8 [; i' w, R
  97. void init();
    , ?4 w; ~; g/ |6 f
  98. void Send_Byte(unsigned char out);. ^+ e2 T! c/ B% g9 k: K# Y
  99. unsigned char Get_Byte();7 ^7 }- J1 E) e5 J) y+ E
  100. void Poll_SO();" Q& t& \( L$ W, t8 c
  101. void CE_High();4 G9 y  `, E% [3 n+ n, ^1 {
  102. void CE_Low();' n$ D/ C0 C7 U9 o) c  Z0 N
  103. void Hold_Low();
    ! b  O9 E" J9 i, N8 q
  104. void Unhold();
    * ^: z6 M5 }. f% P. ^1 m, w+ ]+ T) w
  105. void WP_Low();2 Z, D$ D+ I& S1 I3 _
  106. void UnWP();4 e/ h" q4 b1 z3 j
  107. unsigned char Read_Status_Register();! u( ~8 }* E' }0 J
  108. void EWSR();! K$ p9 E: ?  q8 X
  109. void WRSR(byte);- z" p2 e" E) E& A1 p) e+ ^8 {
  110. void WREN();
    ' C/ D3 R. k6 s, m* B9 r" O
  111. void WRDI();
    " p7 N  a5 w; G2 B2 C
  112. void EBSY();
    5 {5 ~- J# }7 z5 f) T2 V" p
  113. void DBSY();' x  E! k4 t: y) w& G' i
  114. unsigned char Read_ID(ID_addr);+ c$ Y3 {; M) g  {0 P1 f
  115. unsigned long Jedec_ID_Read();
    & {+ ^) s' X4 t: p# |! l' F
  116. unsigned char Read(unsigned long Dst);7 k" `4 b2 B3 J7 X3 U
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    + ^" ^& `) t9 F
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    ; v: x. p, U! I; t0 H5 i0 F
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);' b  O  k0 Y( }7 C  v4 e
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    * x, R& l" ^) D1 w
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    ( L( A, ^) @4 k, q7 @
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);* _" D8 L1 L* @/ x* F- z4 |4 L8 t
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);/ F+ u) @- a& Q
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    ' f5 ]7 c- k7 j
  125. void Chip_Erase();3 V, K& s5 ~0 E# T  N: G
  126. void Sector_Erase(unsigned long Dst);# J3 g9 H9 f3 f8 c7 {
  127. void Block_Erase_32K(unsigned long Dst);
    / E1 @- t4 Z( w9 R$ x
  128. void Block_Erase_64K(unsigned long Dst);2 R5 v7 X# I( S; H1 {0 T
  129. void Wait_Busy();/ [0 @) [7 T/ L; O  c
  130. void Wait_Busy_AAI();
    ) m1 J1 C6 C: `1 W6 F; \6 G' T
  131. void WREN_Check();7 k7 s5 Z/ K  [- L: H8 {* d
  132. void WREN_AAI_Check();
    6 V  n! m$ }+ C4 L8 }" K& R
  133. 2 {* N% }2 V! K0 S5 w/ J( Y
  134. void Verify(unsigned char byte, unsigned char cor_byte);- Q: r; @: Z' m' I8 Q' L7 j

  135. - z4 P3 C6 t  _( P5 C
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    - F$ P* I5 s6 G' @; K0 U
  137.                                                                                 /* to upper RAM area from 80H - FFH */' \% ]2 `! Y+ p7 n" c1 l
  138. $ `9 L) L9 w4 h) `( c/ _8 P$ O
  139. /************************************************************************/
    ) j  N. V3 M: v/ A0 ]
  140. /* PROCEDURE: init                                                                                                                */
    , a5 T' c- t" I' V, E
  141. /*                                                                                                                                                */
    3 p/ W, _8 y* m& P5 u6 F) z) v0 _' o
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    7 z4 X2 m* j" t- Y/ X* q9 O
  143. /* setting up mode 0.                                                                                                        */
    . Q) u# q/ k/ X* f
  144. /*                                                                                                                                                */
    - D1 i; ~. ?2 F% Z8 \9 a
  145. /* Input:                                                                                                                                */  W, V" }; o; x( Q& _
  146. /*                None                                                                                                                        */( V3 d* L6 V2 J. T
  147. /*                                                                                                                                                */
    : Z4 s7 g7 ]' ], I/ O
  148. /* Output:                                                                                                                                */
    ! w) s' X. ^# M$ S6 U8 b5 _) x6 d
  149. /*                SCK                                                                                                                                */
    1 ^7 T( t8 m, j* [6 g* S. a- a& w: {
  150. /************************************************************************/0 P4 V+ ]( B3 I1 T
  151. void init()
    % @. d! C) L6 x
  152. {
    ( R6 I9 u5 B& T' T5 c$ `8 k% ^
  153.         SCK = 0;        /* set clock to low initial state */8 m$ X. E; i  Q5 J
  154. }
    5 ~5 g: K; l: C# |8 v
  155. % j( A& u- h6 E7 O
  156. /************************************************************************/) D% Q! T( Q! g6 w& N1 R
  157. /* PROCEDURE: Send_Byte                                                                                                        */4 w# [/ E! A. e# c! u
  158. /*                                                                                                                                                */4 X4 `2 C$ ?6 k# j1 f/ s9 [8 @( R
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    + T5 ^& Q6 ~% K4 h! M5 g
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    ! u* h) G) N4 W% i! ]& `
  161. /*                                                                                                                                                */% i/ Z  b. N( ^0 ~4 k$ k
  162. /* Input:                                                                                                                                */
    & P1 u! J6 \& x  k
  163. /*                out                                                                                                                                */
    / n) k) a; K' P1 q" r
  164. /*                                                                                                                                                */
    ; K# u# k9 z/ ?. E6 W* t. n
  165. /* Output:                                                                                                                                */5 \. b# ]& |2 A0 l1 V- e, F
  166. /*                SI                                                                                                                                */
    5 {) ]& B! P) Y) R
  167. /************************************************************************/! B  F4 \; H+ a: N  t2 x
  168. void Send_Byte(unsigned char out)
    % l% _8 |! v! n2 C% I4 W& c
  169. {" o" o6 v3 F2 M8 [9 |
  170.         , D. m+ h  B: k! R9 ~& J
  171.         unsigned char i = 0;
    9 I. f: P/ c/ D# p; F* R
  172.         for (i = 0; i < 8; i++)$ X3 B6 s+ a/ v
  173.         {3 I: [! G6 x1 K3 j
  174.                
    , Q7 v8 A; d3 Q4 r  ~
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */! u6 l2 v, G# ?7 @! Y
  176.                         SI = 1;# z5 H( \! M- e
  177.                 else
    4 w* p( ]' `2 ?. a1 ?
  178.                         SI = 0;                                /* if not, set to low */( k% n# m% ~6 G7 P( A, V
  179.                 SCK = 1;                                /* toggle clock high */
    5 `: X' @- [. S3 ^/ Q, Q
  180.                 out = (out << 1);                /* shift 1 place for next bit */, m& b1 G- Q; u  ^4 O
  181.                 SCK = 0;                                /* toggle clock low */
    : P# R4 @- A  c, n; q' z; w3 Q
  182.         }3 _; B8 _: I3 Q- h. b/ b
  183. }4 y5 c- J3 P9 `: G. `$ Y

  184. * V; ~+ b, u5 |- y0 b+ ]
  185. /************************************************************************/. b& E! [+ i, g- t
  186. /* PROCEDURE: Get_Byte                                                                                                        */& P1 g5 B6 w+ ]
  187. /*                                                                                                                                                */
    1 v. I% y* ?7 \" s
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */9 b- N; Z) o3 f5 ?+ `+ l1 _
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    4 q3 _6 y, S' B' D
  190. /*                                                                                                                                                */
    4 A  Z% M, G# o. b
  191. /* Input:                                                                                                                                */" D5 ?* m: Z3 W4 C4 t
  192. /*                SO                                                                                                                                */
    4 {4 B: h; n$ I$ @0 h5 Z
  193. /*                                                                                                                                                */
    - U( C0 @; c: N- T5 e
  194. /* Output:                                                                                                                                */
    : p/ I- L( X4 b) \7 R; E3 r/ ^
  195. /*                None                                                                                                                        *// l% F$ ^& \/ o, T
  196. /************************************************************************/+ V, c0 `# }, B
  197. unsigned char Get_Byte()3 M' \( e8 {" p+ w8 O' a$ |
  198. {8 H3 p6 c  x2 D& p5 h0 l7 J9 J+ s- i
  199.         unsigned char i = 0, in = 0, temp = 0;: p/ W) X4 d. X/ u0 |
  200.         for (i = 0; i < 8; i++)5 ?. i; A7 z6 I# Q: Y
  201.         {
    ! ^) l) {& T: E
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */! s, M5 n) r1 V+ U) ?
  203.                 temp = SO;                        /* save input */
    8 E6 E+ j2 u& P+ q, K
  204.                 SCK = 1;                        /* toggle clock high */
    , {* n/ a3 `# s
  205.                 if (temp == 1)                        /* check to see if bit is high */( v8 g) H# g1 {* B& T
  206.                         in = in | 0x01;                /* if high, make bit high */
    % M( ^( s% n' [

  207. 9 O* k8 z3 c/ r5 `% @1 f
  208.                 SCK = 0;                        /* toggle clock low */
    - z( V( u  O1 V* n
  209. 2 A" D9 b* z* ^
  210.         }
    : N3 |, i2 P3 t. [9 S
  211.         return in;4 Q3 P8 B% I' }& A
  212. }
    ( e3 ?0 b. M5 L( m
  213. - u8 E& f% R! N8 f# ?
  214. /************************************************************************/$ R: r6 t/ {$ d$ _4 G
  215. /* PROCEDURE: Poll_SO                                                                                                        */! d! L. a7 ~* k# q' r1 k/ ^
  216. /*                                                                                                                                                */- q/ ?% x6 S6 @8 X: V7 [
  217. /* This procedure polls for the SO line during AAI programming                  */
    . R3 g7 b# r. `6 n0 q! i
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    / \+ {( x' g4 j2 t" k
  219. /* is completed                                                                                                                        */
    6 j, Q4 z% p& h! c$ m
  220. /*                                                                                                                                                */* ~. J" E; D. C- V! g7 |/ V! m
  221. /* Input:                                                                                                                                */
    ; T) O+ y4 q1 Y/ g+ a; ?$ N
  222. /*                SO                                                                                                                                */
    3 r1 x9 D& x9 d6 Y' H6 c! U% K
  223. /*                                                                                                                                                */7 G! m# B5 I8 W* G& L- E
  224. /* Output:                                                                                                                                */; ]2 H' S0 N$ b5 I* ?
  225. /*                None                                                                                                                        */
    " b+ Y' o: |4 R
  226. /************************************************************************/
    3 H6 r* a! M3 P' u& i6 q( L- J
  227. void Poll_SO()
    " x4 K6 ]' a: R0 j8 ]; w5 J
  228. {
    ) S4 D' P! Y$ g5 J7 Y
  229.         unsigned char temp = 0;
    + ]6 c6 W/ P  }! I# v+ J/ H+ e& `
  230.         CE_Low();6 H/ r  r! G6 Z) V
  231.     while (temp == 0x00)        /* waste time until not busy */
    , n* a3 {2 F! Z8 d. A
  232.                 temp = SO;9 m. N7 f" n* p5 K$ P
  233.         CE_High();
    ; I* c' F7 c; O8 \' G; m: t, c8 c
  234. }# C3 A: z. W/ z* Z% O7 O" p

  235. + A8 u9 C  U2 n; m
  236. /************************************************************************/
    / y8 m8 z9 i; s, h- F
  237. /* PROCEDURE: CE_High                                                                                                        */9 E! c, J; W, s" N4 U
  238. /*                                                                                                                                                */! U8 {# L! {  o0 E& G* Z
  239. /* This procedure set CE = High.                                                                                */  A; ^; R9 w8 d0 w; V
  240. /*                                                                                                                                                */
    $ E( L3 E) y7 g; r$ B& m, ^
  241. /* Input:                                                                                                                                */
    7 }7 V7 f% |$ d
  242. /*                None                                                                                                                        */
      [* }) W* M& u
  243. /*                                                                                                                                                */8 R3 F2 I& M: f/ `  b
  244. /* Output:                                                                                                                                */
    # [( L) m, K9 L4 d+ Y- |
  245. /*                CE                                                                                                                                */
    9 ~' O5 K: T4 b7 N
  246. /*                                                                                                                                                */  y: u4 O+ R7 \0 s& C6 P
  247. /************************************************************************/4 j9 g3 x* v: t4 ]" O  u; V: m! j
  248. void CE_High()
    / e. T+ C  a# Q' u/ b
  249. {& E  R4 v/ T1 J! P: V9 ?
  250.         CE = 1;                                /* set CE high */
    : p3 ?' A' O" R3 s7 E6 N2 l
  251. }8 @; c* X5 h$ A  t1 s$ q
  252.   q5 p/ V- f1 v' }/ @/ ~) p3 @
  253. /************************************************************************/
    7 w6 C8 K- g0 x  L; T
  254. /* PROCEDURE: CE_Low                                                                                                        */# U  ]9 \: Y) w$ T2 i
  255. /*                                                                                                                                                */
    3 Q: e$ {! a8 q& c* W7 l7 A  c
  256. /* This procedure drives the CE of the device to low.                                          */" ]2 F6 Q- f0 I* p( g  p
  257. /*                                                                                                                                                */' X' T2 Z6 J5 Z  ?$ ^6 }$ m
  258. /* Input:                                                                                                                                */
    . A) A; g% X* o( ?' B/ \
  259. /*                None                                                                                                                        */# K& o6 ?) z' s* {  \" s- h
  260. /*                                                                                                                                                */
    7 J: M) x3 S+ c( c0 l- Q
  261. /* Output:                                                                                                                                */( \7 G( e* R3 L/ n9 P8 q
  262. /*                CE                                                                                                                                */
    ! H) a3 I5 }% n9 r' o
  263. /*                                                                                                                                                */
    4 {' N' r* D! L9 v& s: _
  264. /************************************************************************/
    8 ]1 U5 B( q3 {# q0 u* ~
  265. void CE_Low()
    # v7 Z# g$ q7 ^0 u% B/ y( B
  266. {        ! B1 Q- D. P# P3 j
  267.         CE = 0;                                /* clear CE low */2 `' g) V8 S9 h) h
  268. }
    # t8 @# D+ t: d- j  p/ r6 P1 q/ t% C
  269. / ~& Z/ M& M9 ]$ C9 J  c4 |3 Q
  270. /************************************************************************/0 O" R! ]8 Q: r: ?
  271. /* PROCEDURE: Hold()                                                                                                        */" f& e# l' F6 \( s6 V
  272. /*                                                                                                                                                */
      m0 F+ L2 U) v! {1 ~) S5 R( |6 x7 R
  273. /* This procedure clears the Hold pin to low.                                                        */7 y+ y  n9 }' j9 |: |/ b2 N
  274. /*                                                                                                                                                */- o' B- ^  U! A- c# K& Y9 i
  275. /* Input:                                                                                                                                */8 G$ a) ^+ a% k) I; I$ ~
  276. /*                None                                                                                                                        */
    8 K  M( w1 S; W7 l
  277. /*                                                                                                                                                */
    ; R. e, d9 c! T
  278. /* Output:                                                                                                                                */* }- h) d0 t: V( E" c
  279. /*                Hold                                                                                                                        */
    " j# |1 ~- A  J- s
  280. /************************************************************************/: a) ]; b% N, ?5 y
  281. void Hold_Low()- D& I: p7 \5 V
  282. {
    ' H, F& Z1 ^! r
  283.         Hold = 0;                        /* clear Hold pin */
    9 r5 u9 d& m) U( m2 Q1 d
  284. }
    * |. T8 s4 L  ~4 P

  285. 5 `9 |- z% u2 Q' {4 S7 y6 U
  286. /************************************************************************/2 K: N" l" V# g9 d) \7 v1 x0 Z7 V
  287. /* PROCEDURE: Unhold()                                                                                                        */
    4 \5 t0 r5 p$ B
  288. /*                                                                                                                                                */0 [6 N+ R) H* L" u: i- i+ k: `8 W
  289. /* This procedure sets the Hold pin to high.                                                        */
    9 n: e! N' d  d* V9 w2 P0 R
  290. /*                                                                                                                                                */
    # g1 X9 N4 U* Z- H# A" G# @8 r
  291. /* Input:                                                                                                                                */
    % x! {! r% e7 J/ Y/ h3 e3 F. o6 I
  292. /*                None                                                                                                                        */4 A6 g* z2 q. W: E9 ~5 }
  293. /*                                                                                                                                                */
    & u' c* e" K2 q, p; I( s
  294. /* Output:                                                                                                                                */5 d; Z; b1 O" i9 Z
  295. /*                Hold                                                                                                                        */
    ! h# j- a. {8 q* S1 s! k: F* M
  296. /************************************************************************/* \5 O4 G+ q) w1 w- P5 R
  297. void Unhold()
    5 y2 [0 g+ ^1 I. I
  298. {
    7 Z& A5 n0 C0 r( l
  299.         Hold = 1;                        /* set Hold pin */
    " `, D, G8 I: _6 W3 c
  300. }1 }3 T- \1 D# H/ e6 C7 k
  301. - }% z* A5 J5 |2 Z
  302. /************************************************************************/% k) Y# H% v( T. @' P
  303. /* PROCEDURE: WP()                                                                                                                */- }5 g6 C/ ?8 ~. g
  304. /*                                                                                                                                                */
    ) z( c; y6 y- ]
  305. /* This procedure clears the WP pin to low.                                                                */
    4 L: K) B% [- \: o  Q' }7 s
  306. /*                                                                                                                                                */- l" i* h# l6 G# N0 K
  307. /* Input:                                                                                                                                */
    2 T+ @& P- I7 W+ J2 K
  308. /*                None                                                                                                                        */
    * D# I  J8 a# ]) g. a4 `
  309. /*                                                                                                                                                */
    + v3 h" W* s/ e1 W! d3 O9 ]
  310. /* Output:                                                                                                                                */
    * {& K3 W& z6 i  t) C6 r* ?
  311. /*                WP                                                                                                                                */# @; s5 {% s  D0 R8 P* \4 D
  312. /************************************************************************/
    2 \+ e4 q# a) r/ T* e  {
  313. void WP_Low()
    7 F3 n" z+ O* Z) V  \
  314. {
    ) p! Z9 \. c- k. q% O
  315.         WP = 0;                                /* clear WP pin */
    # ?; W$ p* z9 W! e
  316. }% d% U: T. i) y( {( g* s9 G

  317. 2 `6 J# G: u# C( q+ V0 Q, g
  318. /************************************************************************/( @3 `- w+ R7 c( O1 k
  319. /* PROCEDURE: UnWP()                                                                                                        */
    9 Y( g) o- v" b! \3 U9 X
  320. /*                                                                                                                                                */
    % Y' l& t! R3 e) H
  321. /* This procedure sets the WP pin to high.                                                                */( P: V2 m4 h% I5 y# R" \3 h
  322. /*                                                                                                                                                */
    0 O5 s- w8 Q& C8 D
  323. /* Input:                                                                                                                                */- r' |, H. v) b+ l" y7 G/ h
  324. /*                None                                                                                                                        */
    ( |! h# N/ Y# R- N( m
  325. /*                                                                                                                                                */
    2 c! K( I8 T5 S9 \8 V. x% P- I
  326. /* Output:                                                                                                                                */
    8 c% X" M7 Q9 g, _' ?! U$ k( r
  327. /*                WP                                                                                                                                */8 I: b) n) U7 b3 I
  328. /************************************************************************/
    ( e8 W- f! F7 m( D0 s  |* P
  329. void UnWP()2 @5 |9 U3 N; @
  330. {! R: L2 U( c  @1 ]: C  ?
  331.         WP = 1;                                /* set WP pin */) n8 _/ V8 j8 F: b5 Q6 {- y
  332. }* S( l, p# d" P8 u, j1 w+ I

  333. ' N1 G- ]0 s0 @) M' u; U) y/ c2 q
  334. /************************************************************************/6 d0 m0 G7 d8 ~0 `
  335. /* PROCEDURE: Read_Status_Register                                                                                */) v- ^8 c- x. M. p1 G# d4 M1 E
  336. /*                                                                                                                                                */
    : `2 r+ N* |( s( y  r5 @; w$ w. z
  337. /* This procedure read the status register and returns the byte.                */
    3 j9 l& w8 `* h" l4 G( E
  338. /*                                                                                                                                                */' w( [8 ?" c- @, z2 v4 m" c; c
  339. /* Input:                                                                                                                                */9 f- z; D# m9 L9 {" f; |
  340. /*                None                                                                                                                        */
    $ H! f- b1 W$ R! Q
  341. /*                                                                                                                                                */
    ; X/ n1 l2 ^' X/ N% [! X
  342. /* Returns:                                                                                                                                */2 j, g' I7 |- U$ w. F
  343. /*                byte                                                                                                                        */5 |) A" i) @/ y" T* A
  344. /************************************************************************/- V, r  U* A3 C' m: m; V  R  ?' i
  345. unsigned char Read_Status_Register()
    , ~3 |! H8 N0 ?. p+ n( z
  346. {" q; `0 o/ M; |2 Z9 Y
  347.         unsigned char byte = 0;  j7 h1 N) Z0 @8 Q. i0 z2 P
  348.         CE_Low();                                /* enable device */
    & h6 c3 J9 C" S- T% G* a& u
  349.         Send_Byte(0x05);                /* send RDSR command */
    8 [- \7 P% _3 E. I2 T6 R
  350.         byte = Get_Byte();                /* receive byte */
    0 E& q, L1 r: X, u3 A
  351.         CE_High();                                /* disable device */
    1 T9 ~( m) S3 z0 k' ]0 j& H. K
  352.         return byte;. D5 i; I5 L( _6 a" ?- q* F
  353. }
    , O1 N2 {* b7 {8 Y! K% u# s
  354. 9 f. f4 j8 W' Y. y
  355. /************************************************************************/
    $ s+ M: t9 s6 `) k; a  U1 t
  356. /* PROCEDURE: EWSR                                                                                                                */
    . b9 {: E' k" f( H
  357. /*                                                                                                                                                */: i" Q# @# v. T9 `
  358. /* This procedure Enables Write Status Register.                                                  */
    6 @* u( c: K" j+ y7 h0 h0 R# M
  359. /*                                                                                                                                                */5 d* L$ _7 {3 ?; }/ _/ Q; }4 T% P7 k
  360. /* Input:                                                                                                                                */
    3 M* `5 T, s) K% w. X. b$ }% _  R- Q
  361. /*                None                                                                                                                        */
    $ N* Z8 Z$ b) x0 T
  362. /*                                                                                                                                                */5 u2 x& h$ J0 G; n
  363. /* Returns:                                                                                                                                */% ^! T- G; A# M$ o
  364. /*                Nothing                                                                                                                        */
    . l& Y2 S7 `% ]: j# t
  365. /************************************************************************/6 p  M2 |% ~" R  l, A
  366. void EWSR()
    - h. r; S" P! b0 Q8 p
  367. {# }/ M) n) \( p% n- k; N/ O
  368.         CE_Low();                                /* enable device */  C4 t  y: S" q. `7 U4 ?
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    5 D6 Y3 B+ y* k) P" b1 s7 ]" c
  370.         CE_High();                                /* disable device */
    3 R3 O' W* t: E6 F2 S
  371. }  d' e" i' o# F9 P) C3 [+ A# i
  372. # e% B5 B: n  q1 s$ H. ~- e
  373. /************************************************************************/
    4 _% Y" ]% K0 ~! h
  374. /* PROCEDURE: WRSR                                                                                                                */, ?, X- b' x- J' T$ }; Q7 B7 {- }; j
  375. /*                                                                                                                                                */7 c: L, [5 }/ h+ J9 F1 ]
  376. /* This procedure writes a byte to the Status Register.                                        */
    0 e3 `: {% G3 @+ @( x
  377. /*                                                                                                                                                */. `! T! }$ r, A
  378. /* Input:                                                                                                                                */
    & o  C8 Q% Z0 b
  379. /*                byte                                                                                                                        */& b% B  v' s0 J7 n8 ]! r+ J
  380. /*                                                                                                                                                */& g0 F+ P5 H1 A2 }! j
  381. /* Returns:                                                                                                                                */
    7 k" c/ ^# {7 p( s( Y1 D
  382. /*                Nothing                                                                                                                        */& ]7 L: w' f4 j% F; f
  383. /************************************************************************/1 G& M* ^2 t% D1 _
  384. void WRSR(byte). G) t" A( g' n* X8 C: Q
  385. {& z# l  M3 N* M
  386.         CE_Low();                                /* enable device */3 r+ q- {% p  q1 M( Z! X
  387.         Send_Byte(0x01);                /* select write to status register */
    4 z% t0 w9 M$ P7 p7 y
  388.         Send_Byte(byte);                /* data that will change the status of BPx ; u( [( k6 V' Y
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    / S" b$ V# W# {: r2 [
  390.         CE_High();                                /* disable the device */* w) c, W, W' L! G6 L
  391. }/ K: X* F$ @& o9 A1 B: S

  392. % s3 J6 z3 |. t& U0 M; u
  393. /************************************************************************/
    4 E" d) L, W& ?  d" D8 f
  394. /* PROCEDURE: WREN                                                                                                                */
    ( o/ Q' R% @; R: T6 [1 D
  395. /*                                                                                                                                                */
    8 F5 E* ]' A" R$ m5 c
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    % c6 z, f+ e3 y: a5 E) e2 [- W
  397. /* to Enables Write Status Register.                                                                        */. M" o( u; `. R- U3 s% k
  398. /*                                                                                                                                                */
    $ \' v/ D' S- u$ U9 B; i6 C
  399. /* Input:                                                                                                                                */% ?7 V5 @1 y6 E% R! B
  400. /*                None                                                                                                                        */
    ! B3 ]  o$ N+ H. t2 I' w
  401. /*                                                                                                                                                */3 O  p. d* @% `. C. z3 Q
  402. /* Returns:                                                                                                                                */2 }# B; U! j. @7 Y1 c
  403. /*                Nothing                                                                                                                        */# u. w2 [0 j6 h, A. Y, g! n% I
  404. /************************************************************************/6 R9 u6 o9 _4 F! N  @$ f
  405. void WREN()
    . ^! s" ~- ]  r% Q! X
  406. {* u* p6 N2 j5 N  B" P  m
  407.         CE_Low();                                /* enable device */
    6 b4 E  I; A1 j# A% C
  408.         Send_Byte(0x06);                /* send WREN command */* I. t; v/ z9 d0 N+ ?
  409.         CE_High();                                /* disable device */1 S" E5 z8 A  f# \, a
  410. }2 D( }' n, f5 m* C7 [
  411. , ?8 u( k! L+ c7 m- j/ h) r9 b
  412. /************************************************************************/  W9 [2 n% l. N1 Y7 l
  413. /* PROCEDURE: WRDI                                                                                                                */* K0 @( g/ T7 C
  414. /*                                                                                                                                                */
    9 B9 O( H, j& I
  415. /* This procedure disables the Write Enable Latch.                                                */7 i5 T  h7 I# i  F' M; C! [  o
  416. /*                                                                                                                                                */
    ! f. ?) C, O6 m, d, v. T
  417. /* Input:                                                                                                                                */
    ' }/ Y' t4 o) h$ i; \
  418. /*                None                                                                                                                        */
    " U, t' y1 s8 W3 T" v& l3 M4 e
  419. /*                                                                                                                                                */9 H, d  t( H* u/ z% J/ H0 J2 F! @& z
  420. /* Returns:                                                                                                                                */
      Q1 Y4 b) a# r+ c( {4 Q
  421. /*                Nothing                                                                                                                        */. Y" i( x8 E- R  s; U' B; y( ^
  422. /************************************************************************/2 }0 H: c, r5 ?4 ]) e
  423. void WRDI()& ]- O# I+ S3 [% u) x2 A
  424. {
    / \% X: N8 y6 z/ J
  425.         CE_Low();                                /* enable device */
    ! Q9 [1 m7 z/ x4 k+ `& q9 v  x
  426.         Send_Byte(0x04);                /* send WRDI command */& |. {+ p: q2 p0 \
  427.         CE_High();                                /* disable device */4 |* n1 M& y4 ]9 v
  428. }' V; W! E8 u( v7 G0 h' v
  429. 7 g) i* x# i& d! I. M2 }
  430. /************************************************************************/8 \2 T- g8 v' N7 C' E/ o
  431. /* PROCEDURE: EBSY                                                                                                                */5 Z4 A" {# h/ b/ k  m
  432. /*                                                                                                                                                */
      a7 U2 O& c/ x# S
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */# k, F* T- L5 m# c3 t; R0 Z* Z
  434. /* programming.                                                                                                                        */
    3 S7 a) A; ]$ J. y2 a
  435. /*                                                                                                                                                */0 n0 h2 k4 c% K! i3 n" p6 G
  436. /* Input:                                                                                                                                */
    ) m$ ^4 L# ]  m: P) a) D
  437. /*                None                                                                                                                        */
    ) j8 T0 T) E1 g" i" O, R& M
  438. /*                                                                                                                                                */: q/ y' H+ F# @. H) z/ ^& ]
  439. /* Returns:                                                                                                                                */
    + I( C) y8 p$ d, I0 b( [1 H
  440. /*                Nothing                                                                                                                        */, h% b8 w) s. Q& Y" n7 B
  441. /************************************************************************/6 C: L/ O, g  a6 E- ^
  442. void EBSY()6 ]* G4 ?% @9 Y  n
  443. {# H. h. G' k/ _, e
  444.         CE_Low();                                /* enable device */
      R$ S; a& H3 Y
  445.         Send_Byte(0x70);                /* send EBSY command */% p1 B$ @8 F; H7 L0 X
  446.         CE_High();                                /* disable device *// @% p) F7 n9 R- j
  447. }* i2 [0 h' X7 ^6 C: m

  448. - Q  x( q; {5 v& S7 I/ z
  449. /************************************************************************/3 t2 v: W. L3 }) G: e+ Q3 Q
  450. /* PROCEDURE: DBSY                                                                                                                */
    ! l% U+ C, f9 k3 u: p$ [
  451. /*                                                                                                                                                */9 z6 z* t% x; y. g" D+ H
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    ) A1 z! D& K' P- D  ~
  453. /* programming.                                                                                                                        */$ g' s: U" h+ v* a2 H/ @) w
  454. /*                                                                                                                                                */" l0 D1 M; D* o6 `, ]. ^
  455. /* Input:                                                                                                                                */
    ( A$ e! w- @% d% `! z# J
  456. /*                None                                                                                                                        */  D( r. q9 }5 Q7 d" X) t
  457. /*                                                                                                                                                */# V4 G+ h  b8 I8 A3 w9 a8 B
  458. /* Returns:                                                                                                                                */  [0 Y4 W) i; H
  459. /*                Nothing                                                                                                                        */
    % G4 q: f9 ]3 X8 F! V# B& k" T( f$ V
  460. /************************************************************************/
    4 {5 Z* N3 K! }4 H2 a6 ]
  461. void DBSY()
    . l7 V' ~5 k8 Q2 V
  462. {
    1 k# d6 }8 T) {5 ^
  463.         CE_Low();                                /* enable device */
    % R( N6 ~1 p4 U' t" P
  464.         Send_Byte(0x80);                /* send DBSY command */7 K9 _* W0 ^3 U8 K7 [4 j
  465.         CE_High();                                /* disable device */
    9 \0 m6 g% F$ H" e" k$ r! b* a
  466. }
    6 v) S8 @' {" F) \& z
  467. ! I5 ~0 C5 m3 }+ ?
  468. /************************************************************************/; o9 K3 X, M/ F1 b$ R( G
  469. /* PROCEDURE: Read_ID                                                                                                        */
    / q- k# A$ M; Z+ ]
  470. /*                                                                                                                                                */; E# z# p, K" r9 K; U
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    0 _! p3 ]3 e6 k- \
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */# Y9 G6 o( t4 N
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    * `" s" M6 Z) L- [8 G- S/ d
  474. /* whether the device outputs manufacturer's ID first, or device ID         */7 g. x9 L% z. i/ G2 F% ]
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    ) `$ R! C: U% e7 {( J8 R
  476. /* variable byte.                                                                                                                */
    ' o- Y/ v( ^0 e5 u
  477. /*                                                                                                                                                */! k, j5 q6 ~+ a* a
  478. /* Input:                                                                                                                                */
    & l; }# v9 A( I2 c1 o0 R9 v
  479. /*                ID_addr                                                                                                                        */
    ! K& B' c/ ?* i. c$ `; T$ _
  480. /*                                                                                                                                                */
    5 ?  p; c8 T# u  ?9 c
  481. /* Returns:                                                                                                                                */
    % R' m+ x+ x. _, n3 E6 k* \5 T1 Q+ C% a
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */* p  s' E7 P& x1 O
  483. /*                                                                                                                                                */- v" i. r+ m! @5 [5 M( |: v/ P
  484. /************************************************************************/
    + |" ^* Q/ p0 w) _) N) j' |
  485. unsigned char Read_ID(ID_addr)
    " _# B( ~4 X; a# V1 g) F9 f
  486. {
    ! F# K; Y9 B! m; g& v
  487.         unsigned char byte;
    $ J& D, k3 J5 T( I# Q
  488.         CE_Low();                                /* enable device */
    9 t* y- f+ ^, ?. \, N
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    $ c! w( h: U% l8 _  Z* N
  490.     Send_Byte(0x00);                /* send address */6 F9 I$ G! \  o7 w9 I4 A0 ^
  491.         Send_Byte(0x00);                /* send address */5 W; c/ R8 K: C+ @
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
    ; ^5 \& ^: Q% W. }- P+ ^7 j/ m
  493.         byte = Get_Byte();                /* receive byte */
    * d. o. f* R2 T. `
  494.         CE_High();                                /* disable device */
    4 ^3 Y! \7 J  v# h5 v: Q) b7 O. ~
  495.         return byte;& L1 x5 z8 R. m* P# X# _
  496. }2 h2 d- c$ y9 r
  497. + ?! w7 ?- `- D
  498. /************************************************************************/) e  j* f5 g9 s, c9 t5 w
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */! d% y$ x0 B; \3 w' k4 e
  500. /*                                                                                                                                                */. K  k6 t, N! g) x% @3 m! P. L8 l) F
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */- }. t" A4 n% U  \; M3 c, x! a
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */' `: L# M3 M5 Z/ _( N1 F
  503. /* Please see the product datasheet for details.                                                  */
    ( g( O% W& a" y, O
  504. /*                                                                                                                                                */, u+ \/ ~  s7 k$ C' X5 R2 U
  505. /* Input:                                                                                                                                */
    2 n) x, W8 B" ]2 I3 P" f
  506. /*                None                                                                                                                        */
    & G) {1 T( z* F5 A5 A% F; @  |
  507. /*                                                                                                                                                */
    . F8 ^) B$ D/ {) E5 p* E
  508. /* Returns:                                                                                                                                */. A' B0 p2 D$ L9 R7 O, A+ N
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    : `' N1 O/ |" t; H; H  h: S
  510. /*                 and Device ID (8Eh)                                                                                        */
    2 s0 d# Y( N2 G$ O1 C; Q7 p
  511. /*                                                                                                                                                */
    ) w# @% t% s3 B* t3 R
  512. /************************************************************************/
    - Z- G5 k8 V- c3 B# j1 q! j
  513. unsigned long Jedec_ID_Read()
    : `8 `5 W% L2 J! O
  514. {
    7 F" v% X" N, |/ G6 n
  515.         unsigned long temp;0 E  M, W+ U4 ]( W5 g0 y0 J" i. z+ s
  516.        
    ! Y  n( d9 j% A: X- ^
  517.         temp = 0;
    1 x0 X8 {9 r2 v8 r4 c; K6 N

  518. # N7 F) B0 D& k2 @% m4 v) u$ Z
  519.         CE_Low();                                        /* enable device */
    % U) G0 ]* c$ |& a4 r# Y" a/ N
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */7 g: H+ i' K" f. t1 i8 J
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    1 G6 E1 \0 v/ s$ R. ?
  522.         temp = (temp | Get_Byte()) << 8;        . R3 b0 I4 u7 Q" [2 [
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */# `+ r/ g6 k$ Z2 Y
  524.         CE_High();                                                        /* disable device */
    % E/ s2 }) h; L- T3 o
  525. 0 ^% Z0 g" x" W3 i0 Y
  526.         return temp;
    , {' W" ?3 O) f* s5 t
  527. }7 a; v4 U2 \1 p7 F  R
  528. 3 t) H' a: B: c6 g5 i. P# U0 }/ X
  529. /************************************************************************/
    9 o. {* [* F& c2 h* w2 I; U9 M
  530. /* PROCEDURE:        Read                                                                                                        */0 w* L5 m- g" y% c3 U" S
  531. /*                                                                                                                                                */                . g4 ?. c& w0 n# w3 L
  532. /* This procedure reads one address of the device.  It will return the         */7 t$ w4 M* l% G3 s( h
  533. /* byte read in variable byte.                                                                                        */- l/ u8 s$ G3 j0 \8 t& t; w
  534. /*                                                                                                                                                */
    & a+ M1 ?) X2 K1 R' y7 K, i
  535. /*                                                                                                                                                *// y8 p$ a. k- u* ~
  536. /*                                                                                                                                                */8 C' v% k7 W: P3 q3 g# l
  537. /* Input:                                                                                                                                */1 K. O0 E2 Y+ o% E7 f
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    4 d) x3 }- W: [  j
  539. /*                                                                                                                                      */
    : p0 {3 L- U: r+ d
  540. /*                                                                                                                                                */! m7 |& a- v8 d6 f! i1 g! Z
  541. /* Returns:                                                                                                                                */
    $ e) U6 n, n( c
  542. /*                byte                                                                                                                        */
    6 V$ I4 g/ n7 X4 B0 O5 b! w) I& D' V
  543. /*                                                                                                                                                */2 {2 ?. L# c8 c/ c
  544. /************************************************************************/& p9 ~4 k" h, g6 Z9 G% N2 p/ {
  545. unsigned char Read(unsigned long Dst)
    # Z  P9 w3 R" Z3 I2 F5 B( u
  546. {
    6 z: ?7 n+ r3 H0 c1 K) v
  547.         unsigned char byte = 0;       
    ) X* c6 @, Y! E5 P! G* p" b9 ~- F
  548. - Q0 w, p' R: _; {1 m
  549.         CE_Low();                                /* enable device */
    ! W0 _; l+ G) b2 W
  550.         Send_Byte(0x03);                 /* read command */0 f. n% \) l; l0 z8 L" W6 t" h8 x
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */1 k; Y. `, A- A' J
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));3 V+ V4 ?+ b" X6 E0 K
  553.         Send_Byte(Dst & 0xFF);
    , M4 w' g" H$ B) p( h2 p  v
  554.         byte = Get_Byte();
    ' L  S3 r# M4 m% v: P" T  F& J
  555.         CE_High();                                /* disable device */: a4 N3 [4 n$ D# e( Z+ W: I, T
  556.         return byte;                        /* return one byte read */$ S2 S4 @. L- d4 M( j+ K! o
  557. }
    * ]( R9 y2 M* f. j8 \4 K
  558. $ K) w2 ~' q" k9 M
  559. /************************************************************************/; G- e* {3 t& H
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    - \! b- g/ ]1 l1 V/ h; F: v
  561. /*                                                                                                                                                */               
    : n) Q9 K) b& o" ^' R
  562. /* This procedure reads multiple addresses of the device and stores                */
    9 @4 V( M" o. U
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    & a- Y/ v3 x" {  _% }0 [
  564. /*                                                                                                                                                */
    : E& ]( Y5 J3 h* l" |) N. C
  565. /* Input:                                                                                                                                */; G: ^4 g: a7 ?/ m, E
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    8 E1 K3 M  d  z; J+ E" |2 w% Q
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */. Y, O& e9 r4 G; c/ i
  568. /*                                                                                                                                                */
    # z+ b1 p: D' c( J  q' z/ `- i1 O
  569. /* Returns:                                                                                                                                */
    0 {* E/ v$ {2 C% b( Q" @
  570. /*                Nothing                                                                                                                        */& ~- a# ?2 f) D+ x$ ^
  571. /*                                                                                                                                                *// d# U* I  `: {
  572. /************************************************************************/6 \' ~8 f3 a+ p2 A/ S: y6 N
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)- Q- y) Y: Y" @% L( F; w
  574. {
    ' r- u$ h, M/ o
  575.         unsigned long i = 0;! F8 g3 g7 E- L) U; E' n9 I2 _
  576.         CE_Low();                                        /* enable device */3 n- l6 ?5 Z( U: N$ q
  577.         Send_Byte(0x03);                         /* read command */
    8 Y3 T: \9 C' p* i0 f0 v7 ?/ c
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    * @4 }2 Z5 G: p" \9 P+ P. k
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    1 y, H/ P" q2 f" n
  580.         Send_Byte(Dst & 0xFF);
    7 r; r# `$ |# }! d, [- X) R4 D, X
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */) f+ \; a+ Y8 d' r
  582.         {
    2 x  C4 b8 S& O* l* h9 W
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */5 D- a6 k% G6 g, u" U# Q
  584.         }
    0 {. w; {& _6 _& ~2 f6 D
  585.         CE_High();                                        /* disable device */  K8 @3 c4 S8 S' ^9 ?# m

  586. ( {& \+ m8 {) o; `! Y
  587. }. a$ T" o) B! s) ~# y, P
  588. # ]& K; }% h/ _9 }
  589. /************************************************************************/
    ! K0 T( [: k8 `2 e2 r
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    0 }% \8 `. S3 x. V: g8 q; ~
  591. /*                                                                                                                                                */               
    & D0 E) C7 R( ?& }. p4 N5 }
  592. /* This procedure reads one address of the device.  It will return the         */
    0 v7 Y& R8 G1 P
  593. /* byte read in variable byte.                                                                                        */
    9 G0 F3 x$ x( @* l
  594. /*                                                                                                                                                */" F7 f$ C4 P: H5 F; A: N
  595. /*                                                                                                                                                */
    ' d4 ^- o% O% a5 t4 C8 _, W  Q3 p% c
  596. /*                                                                                                                                                */
    + l3 H! p/ k; Y" M/ b# s
  597. /* Input:                                                                                                                                */
    2 X+ E0 B/ E! L3 x1 w3 ~
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */) m+ v& F. K6 ]# l
  599. /*                                                                                                                                      */" {6 ~# i0 N. P( N3 T& g. }7 s8 N- W% n
  600. /*                                                                                                                                                */) m1 w  i7 v! U) D, W% p5 U" t$ B1 U
  601. /* Returns:                                                                                                                                */
    , o" O; ^2 I5 A5 R# r. {/ u
  602. /*                byte                                                                                                                        */$ |. o$ f0 V- |1 i/ z/ `/ v0 E8 x7 N
  603. /*                                                                                                                                                */$ w* d% u: J* o3 V
  604. /************************************************************************/
    ) a! o( q0 }0 J0 r
  605. unsigned char HighSpeed_Read(unsigned long Dst) ( d9 n) k! U: i, O) \
  606. {: ]6 r& Q/ r# U! n. P+ K
  607.         unsigned char byte = 0;       
    . T0 u0 a2 O; N9 V6 P

  608. : ~9 q* v) N; v0 r, m5 M* H. F/ ^
  609.         CE_Low();                                /* enable device */
    " K  m* E& d3 O# s$ D
  610.         Send_Byte(0x0B);                 /* read command */
    9 U; U. {8 [2 N5 c% i
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */+ B( m1 q. s& ~; O
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));( q8 P" v+ v" E. l  _
  613.         Send_Byte(Dst & 0xFF);
    9 [, b% |8 H/ U; t9 t6 Y
  614.         Send_Byte(0xFF);                /*dummy byte*/
    6 \) ^6 B) e' `
  615.         byte = Get_Byte();. ]6 r1 V4 i# V, a' d' g. E
  616.         CE_High();                                /* disable device */4 b3 A. n. H! W. u* N) ]2 g
  617.         return byte;                        /* return one byte read */" b2 S4 P7 P  |* w3 F7 [% F( D
  618. }4 J) C4 V" y- {1 w! k. H( ~+ M

  619. / P9 b* a/ E- m$ `* k
  620. /************************************************************************/& C7 j* `& B' r4 A
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */$ k8 ?0 m( S6 ^5 c9 h
  622. /*                                                                                                                                                */                $ V* ^6 q  P$ r' m
  623. /* This procedure reads multiple addresses of the device and stores                */
    $ o: R: ]2 I+ k, m5 J7 T
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    8 t0 n  ~, J1 Y( W( B) m/ f5 }7 ^
  625. /*                                                                                                                                                */  v- k2 G( g+ \
  626. /* Input:                                                                                                                                */) M; x' q6 ~$ u
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    1 q, ?! s4 r% j4 P% e% |5 \
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    . B7 j: V/ f) y3 x
  629. /*                                                                                                                                                */
    1 `9 C" {+ C: \
  630. /* Returns:                                                                                                                                */
    # ^/ L1 U' o3 o' {' t+ i
  631. /*                Nothing                                                                                                                        */) y0 n$ O8 B6 N* O
  632. /*                                                                                                                                                */, v/ Z: C) j2 C0 U
  633. /************************************************************************/
    , `) t  Q0 E% m1 @/ P; ?: \
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    ; y! x3 A( u6 d' J" {0 L
  635. {$ p5 c# G" P7 |+ ?5 |
  636.         unsigned long i = 0;7 a( b6 k. V2 `6 d# V& ^9 W  a
  637.         CE_Low();                                        /* enable device */
    ' L6 t8 _2 e, T* W. i
  638.         Send_Byte(0x0B);                         /* read command */5 y3 {3 S) d4 X6 j, U1 a& o) S
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    # b& i) h7 m* t
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    8 W, i; c. c& ?& w/ z7 m" ]
  641.         Send_Byte(Dst & 0xFF);3 {* F% }  h# ^; D' E+ _1 g5 h2 i0 X
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    5 a: V3 q7 Y5 Q* i: ^9 |1 n
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    % O4 X7 S1 \! _8 x0 w
  644.         {
    3 e9 J' P( q: e8 N  `. u9 e, j
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    1 d- J6 Z" L! o/ c1 V
  646.         }  L9 K% ^( t) j
  647.         CE_High();                                /* disable device */+ m7 ^% n: e1 L' p7 {; ?7 G
  648. }) z% d9 H! y. D1 K) I% e3 l
  649. 2 ^. m; g+ G2 ^1 R+ c4 B
  650. /************************************************************************/
    : e( w) U+ i% d; T
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    5 z# p2 C) q9 e* |& Q3 U- Z
  652. /*                                                                                                                                                */3 y' Y; F1 J# I* o5 Y3 o/ [0 B
  653. /* This procedure programs one address of the device.                                        */" B6 z- Z# e3 P
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    5 @2 A4 \  k6 w; o/ x
  655. /* block protected.                                                                                                                */
    3 b4 K- \$ c$ [& l) p
  656. /*                                                                                                                                                */2 E# U- q6 B' j7 O3 P4 ~1 ~0 Q
  657. /*                                                                                                                                                */  c% k2 f4 a/ I! L5 j* H
  658. /*                                                                                                                                                */
    5 {* n1 Y' ?% O2 ]; W7 |
  659. /* Input:                                                                                                                                */2 j8 {8 q3 a7 b, `: M
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ' `3 b! W2 N0 x! P" x+ ^6 Z- A3 O0 h
  661. /*                byte:                byte to be programmed                                                                */8 M7 j, o& h, y8 x# c8 s
  662. /*                                                                                                                                      */
    2 a! W) a& V5 c2 c$ |
  663. /*                                                                                                                                                */: M6 G% c6 y& ?( m3 T6 O
  664. /* Returns:                                                                                                                                */* ^: v0 \0 X4 n
  665. /*                Nothing                                                                                                                        */
    : \0 C5 z+ n' L% B$ C. `+ j
  666. /*                                                                                                                                                */
    0 m, e" o$ w8 n5 W+ H5 _. k
  667. /************************************************************************/8 D3 j( i# S5 B: E1 o
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    9 ?, ^( t3 h9 d5 O- {0 v. k
  669. {
    ! v0 J* B1 J) `% U  l2 a
  670.         CE_Low();                                        /* enable device */
    # S# j5 x# r7 I; x0 O8 {3 q
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    ; H5 _: j& g/ v# B
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */5 F9 V: K1 c  T
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));+ ?7 A' n$ M! S7 f" R9 F
  674.         Send_Byte(Dst & 0xFF);
    ( M) K) h. P" n3 h8 n+ _/ Q
  675.         Send_Byte(byte);                        /* send byte to be programmed */9 I4 x) o# m" l  R9 K: F  O) _
  676.         CE_High();                                        /* disable device */
    ' `! i  W) ~/ w' D: V# {7 R+ w
  677. }4 F* j/ X# m: ^$ @$ ?2 @+ E

  678. - u: s( Y6 @# E% A% ~
  679. /************************************************************************/
    7 S/ T6 s& [6 u. M8 ~8 S
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */  A! M9 f- ], l3 T
  681. /*                                                                                                                                                */
    , o. k( F- l  z% u# ?0 A4 t
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/# s: @; R& A6 \7 p9 e; v
  683. /* the device:  1st data byte will be programmed into the initial                 */
    + K3 K* s/ D' ^5 X8 ^3 S$ o
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */( t! o* m; C# s' F5 E5 |
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    2 q( P) G; ]$ I6 Q, k. o  @+ W! C
  686. /* is used to to start the AAI process.  It should be followed by                 */
    - d  W" M% b, k2 N" G; N4 i, z
  687. /* Auto_Add_IncB.                                                                                                                */4 b* p' z% c( N1 T8 M- P8 d
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    8 W8 R; O) Q& O! R. \
  689. /*                                block protected.                                                                                */
    * X  Y4 f7 D3 l7 J0 W! h# t
  690. /*                                                                                                                                                */
    5 s( Z7 b7 a% l  o4 x
  691. /*                                                                                                                                                */) n8 K+ n! K! v
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */& {" H. K9 u8 }! C, ~
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */5 |4 ?- ?# v" B
  694. /*         unless AAI is programming the last address or last address of                */
    " P; g, b6 }; w0 I( ~( d( s
  695. /*          unprotected block, which automatically exits AAI mode.                                */# o9 u) r5 ?/ I( j
  696. /*                                                                                                                                                */9 V, R5 i  g) |4 D. ^
  697. /* Input:                                                                                                                                */
    + k4 J, E* h' v7 a4 z
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : i& b2 T* ~! Q9 i# V$ T
  699. /*                byte1:                1st byte to be programmed                                                        */, ~! F  t1 m3 s  V( M; K
  700. /*      byte1:                2nd byte to be programmed                                                        */
    3 |3 Y/ R4 u& \% l/ r7 |3 [
  701. /*                                                                                                                                                */
    1 E6 N& z* |% `# r1 n; P
  702. /* Returns:                                                                                                                                */" h2 r4 d9 l5 k3 [0 x5 [  v2 t
  703. /*                Nothing                                                                                                                        */( U* P0 b" n# [% `! G+ W2 c
  704. /*                                                                                                                                                */! K3 Z% {4 a7 R1 X3 Z
  705. /************************************************************************/1 p; Y. W& d; \5 Q2 u: C5 L
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    & @9 s! u0 x: I& U  Y; {
  707. {! e) a; Y* F' S* H
  708.         CE_Low();                                        /* enable device */8 l7 u4 V7 s: ~- r) {6 T  l
  709.         Send_Byte(0xAD);                        /* send AAI command */
    ( ], g6 X( {. D
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */& k+ J; d# O: G5 N
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    2 R9 r  F. \3 Q, w
  712.         Send_Byte(Dst & 0xFF);6 G5 V+ d' q+ B* r6 S
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    1 ?$ T' S. M% j/ ^, n
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ' i6 ?+ t5 S0 ]7 r( P
  715.         CE_High();                                        /* disable device */# ?" l% W" T- q  ]* G4 `
  716. }. o" S( @8 |: j
  717. . Q2 [9 o9 a; P
  718. /************************************************************************/
    ( P* p3 Z9 `  R, M
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */: B! v" [# o9 J3 F. D. q
  720. /*                                                                                                                                                */. o2 m: l* j1 Y+ [. Q0 q% X4 P
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    $ i9 |. A5 H) C4 C( D% b
  722. /* the device:  1st data byte will be programmed into the initial                 */5 w% w) i* b: {+ S; P/ s2 i+ e4 k
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    ' b3 q9 c  d# `
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    7 j& ^! o6 [0 \, [4 m" s
  725. /* is used after Auto_Address_IncA.                                                                                */9 U/ s  E6 \1 ?4 ~: v
  726. /* Assumption:  Address being programmed is already erased and is NOT        */! s" ~7 `% Q5 e# J
  727. /*                                block protected.                                                                                */
    & ^& J" x7 M" ?: D$ ]/ A- }& x) ^3 q
  728. /*                                                                                                                                                */
    # U7 G' f, A& {! b0 l# g
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */( U5 u3 H1 t/ H& m, i% ?7 o% L+ L
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
      D( h9 e+ |/ _! O+ u; l7 m2 d( G& V3 ^
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */! x. b  B0 p/ P/ a2 x; v
  732. /*          to exit AAI mode unless AAI is programming the last address or                */! b( x6 H( h( u$ O( X( P3 \4 D
  733. /*         last address of unprotected block, which automatically exits                 */
    1 ]* y, \% U, ?" _' H8 L
  734. /*         AAI mode.                                                                                                                        */: c* z! H  `: p+ w7 D5 V" Q
  735. /*                                                                                                                                                */7 D- @8 ^/ c8 v! M3 E: O( e% @1 u
  736. /* Input:                                                                                                                                */
    . c" E( e7 ]* `; {/ v
  737. /*                                                                                                                                                */
    ! X8 _8 a6 e- h0 M* K- p
  738. /*                byte1:                1st byte to be programmed                                                        */6 @% m' n4 a4 H( E
  739. /*                byte2:                2nd byte to be programmed                                                        */
    3 V2 @& s9 k* V* U3 G
  740. /*                                                                                                                                      */4 Z: L' C4 ~7 g
  741. /*                                                                                                                                                *// F) h  n( k" U2 k& W1 s
  742. /* Returns:                                                                                                                                *// b8 X: C3 n" g6 s: l) ?9 @
  743. /*                Nothing                                                                                                                        */
    . r/ I0 O5 _8 j" U: J. ]
  744. /*                                                                                                                                                */7 l- e* F) F# o( Z
  745. /************************************************************************/3 ^( e' ]7 V. b+ G+ }0 B
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)+ v6 i+ c/ T1 C6 ]' i1 \; ~7 O
  747. {7 a% S+ k6 T$ W4 ?+ {+ z1 j
  748.         CE_Low();                                        /* enable device */
    . m6 W6 O7 ^9 U- a& W( l6 }& P
  749.         Send_Byte(0xAD);                        /* send AAI command */; K+ h! I& s/ l- u7 C) ~8 f7 ]
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */2 A! m" o9 M' M1 v. G
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    + g( d; z% T7 c7 g) H( R' F, _1 j, |
  752.         CE_High();                                        /* disable device */- O8 n$ O3 p! k) O# a
  753. }6 o# f0 v$ l4 l& b

  754. 3 f* `7 e9 t& p6 ?/ P1 h2 y
  755. /************************************************************************/
    2 p' M" d  O  C7 a+ K
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    - d! Z. M( Z$ G( n$ s
  757. /*                                                                                                                                                */1 U1 O5 D/ J4 J# M3 P
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    4 h" g1 a3 h% Q0 h8 N- z
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    % |% }! W$ _' Z! U6 N  W8 j
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */% C. j6 R) d9 K. }' y
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    ! ~' j: m+ m4 [# L
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    9 D$ U9 H/ c, w% ], z
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */% G. |5 e- p+ }9 b$ a
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    ' \1 G8 K5 Q* E! i  b8 Y
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    , v& e0 Y- Q0 o
  766. /*                                block protected.                                                                                */6 \5 u* b6 f: @5 R5 s
  767. /*                                                                                                                                                */
    - o; @6 t3 [' H( U
  768. /*                                                                                                                                                */# D) ~3 l4 g8 h3 E9 Z! n: K! R
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */3 q, {9 V4 Q0 v  j! e' `' r
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    1 |3 x* W( D& q
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */4 f6 V  c5 h5 m" @1 W+ ~6 C! d
  772. /*          to exit AAI mode unless AAI is programming the last address or                */, v% J/ Y& F' w9 E7 {% O% f: f5 D' r
  773. /*         last address of unprotected block, which automatically exits                 */
    ( E" e1 E- A- K/ r3 U. ?
  774. /*         AAI mode.                                                                                                                        */
    7 C+ M; e& Y+ f
  775. /*                                                                                                                                                */
    3 J% Z$ \1 _# R, D8 R/ t
  776. /* Input:                                                                                                                                */
    ; @  `9 ?! F2 `% t" o# c
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : U( ~2 t6 Q' p- a
  778. /*                byte1:                1st byte to be programmed                                                        */# c" P( m" v' W: c7 p8 ]5 @- x' f
  779. /*      byte1:                2nd byte to be programmed                                                        */
    ; u' \. m, k9 Y/ m( `
  780. /*                                                                                                                                                */
    5 ~$ K  t2 Q8 J' j
  781. /* Returns:                                                                                                                                */2 P/ O. W. P" q1 `: {, Y
  782. /*                Nothing                                                                                                                        */
    & w" V# \" N" `/ |7 m" u. \
  783. /*                                                                                                                                                */. w. Z( g, Z3 C2 _0 P4 k3 W
  784. /************************************************************************/9 M% t% @  @0 `
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)2 s" r$ }5 p7 p4 m
  786. {
      X# }+ s7 Z+ {" a
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    1 M2 _, q# c0 A6 T# K* \: x' t) `! l
  788. $ k% Z* A  T" v; R2 Z- s, g/ n2 L
  789.         CE_Low();                                        /* enable device */4 f' ]" H' ?* h2 Q/ Y0 i
  790.         Send_Byte(0xAD);                        /* send AAI command */
    ' z% G7 p$ e5 G2 B& w3 x& a6 ^8 O
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    7 k0 U0 P2 a+ o
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));1 O" H0 p) n1 K
  793.         Send_Byte(Dst & 0xFF);
    ) e8 M: ?5 O* c/ q; `  P9 V
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        ' t6 E: h) E/ b2 J1 M6 T* _
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed *// b1 t0 y2 Z1 h
  796.         CE_High();                                        /* disable device */
    9 [% j0 e1 v5 l! i( R
  797.        
    4 I( m9 N6 r4 R6 J
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */" i( U  q* P! }
  799. % i0 U7 l: z* z, t2 }
  800. }) E! I% E/ E. H. [$ e
  801. ' S4 p2 U( ?+ }4 q
  802. /************************************************************************/; K% S8 D# z3 b9 v
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */& m9 h' d" W- I) ?8 R, l! g4 I
  804. /*                                                                                                                                                */  Z2 D" W( [! a( h+ ^
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */' q  l' x2 k) Z
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */; R! ?4 k: S5 _2 j7 l
  807. /* AAI programmming is completed.  It programs consecutive addresses of */- r. Y; M# e( B. A  C, {+ \: z2 ?
  808. /* the device.  The 1st data byte will be programmed into the initial   */! h5 A1 V$ N+ j% {
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    4 E! Q/ O: j0 x. @( p
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */0 u, n4 X$ v. [1 T+ d7 ^
  811. /* used after Auto_Address_IncA.                                                                                */
    + a, d( E- A& H; O' b% S
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    ( o8 M' a' C/ k8 Y( X3 [: `
  813. /*                                block protected.                                                                                */2 W8 Z# y+ Z: g5 \, [2 ?& }1 m/ T# }2 n
  814. /*                                                                                                                                                */6 `2 f1 Y& T3 K/ Y/ s
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    * a9 I) b& P: I# a" |3 `
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */- J. }1 a+ k& T6 z
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */5 }6 P/ m- \  Y; g, r, e+ C
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    . m, ?. F( T! n5 `& C  ~+ o( k+ E
  819. /*         last address of unprotected block, which automatically exits                 */
    " A" u, F- I+ D7 d. f
  820. /*         AAI mode.                                                                                                                        */
    6 ?, w( k6 |( t+ R5 ]1 _
  821. /*                                                                                                                                                */
    ( g1 N5 n( C7 g: ~( u1 A
  822. /* Input:                                                                                                                                */, x+ f1 b9 x2 d% C  D  E+ K
  823. /*                                                                                                                                                */
    " {9 C6 K. X2 E, B- V
  824. /*                byte1:                1st byte to be programmed                                                        */
    2 i) M. |. ]- j! `5 O
  825. /*                byte2:                2nd byte to be programmed                                                        */
    * }2 `. e! C) `5 `8 x2 V
  826. /*                                                                                                                                      */! ]3 P  D1 @$ H! ?3 f( [* R
  827. /*                                                                                                                                                */
    ) T+ G3 [- n" p  }/ f5 c
  828. /* Returns:                                                                                                                                */
    ' u8 z# _) I* K$ b) P) S: B
  829. /*                Nothing                                                                                                                        */& A1 K" {; I+ k
  830. /*                                                                                                                                                */
    / K9 B. H1 w5 J7 i
  831. /************************************************************************/
    5 u  ?& X; R4 j
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)( T' q" ]7 D1 s& _7 n, f/ F
  833. {; t: Z% ], L5 b  a8 W3 B* C
  834.         CE_Low();                                /* enable device */
    $ O; |# X1 ^, F6 C2 W) B
  835.         Send_Byte(0xAD);                /* send AAI command */9 [: H$ O. r& j4 |. ~) p
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    , V7 N) A$ E! _7 B* f: {; ?3 X; v
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */1 m4 D. I6 _' x5 [8 d, ^
  838.         CE_High();                                /* disable device */3 L3 \; {$ E  H
  839. $ u, E3 k1 ~" \* t7 c. U
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    ' K- c( V2 v# n5 t

  841. , ]) Z6 H  Q( H; F3 `% R
  842.         WRDI();                                 /* Exit AAI before executing DBSY */9 U+ f% h( ~9 O& v
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */3 Q  X% M9 q( y2 n) Y0 A
  844. }, `& a5 i/ G7 P) F+ W' x) L
  845. $ f$ S. T' [! o
  846. /************************************************************************/; V( y$ u4 F+ |
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    % y! Y* x7 ^# x5 Y. {
  848. /*                                                                                                                                                */
    8 _6 U4 F4 L% `7 s! i9 X
  849. /* This procedure erases the entire Chip.                                                                */
    $ z, D! h- T4 W
  850. /*                                                                                                                                                */& m8 {" U& ~* Q3 S3 W
  851. /* Input:                                                                                                                                */4 b/ u) H" I; t7 a
  852. /*                None                                                                                                                        */
      {' E( S+ F# F6 m% l' J2 z
  853. /*                                                                                                                                                */
    3 w4 D0 m! b: M# n6 E
  854. /* Returns:                                                                                                                                */
    # t, O' u: a7 b5 M# Y
  855. /*                Nothing                                                                                                                        */0 m0 w  v  e+ f  _. @! B
  856. /************************************************************************/: `$ e, u" U% l+ m
  857. void Chip_Erase()! C& J% {2 l- t3 ~) B: s& x7 y9 \
  858. {                                               
    4 t2 o7 z1 _: \% v$ I0 a
  859.         CE_Low();                                /* enable device */
    1 n; R* w5 `/ ?6 k
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */$ A3 `& R, \* i" p5 @
  861.         CE_High();                                /* disable device */
    ' G! E! |8 t1 j
  862. }
    0 w$ L7 U" V, I( q" f% Z+ i
  863. 5 S6 v5 _! K3 J
  864. /************************************************************************/9 _* |* c' S! A9 I; o4 N: R7 o$ a
  865. /* PROCEDURE: Sector_Erase                                                                                                */, n3 Y* C7 [5 d  m; M
  866. /*                                                                                                                                                */2 k6 f$ s( L, N8 n
  867. /* This procedure Sector Erases the Chip.                                                                */1 m" [: g0 _, g  O6 c9 s4 z; J; s  s" Z
  868. /*                                                                                                                                                */
    " y; D3 c, ]' q( H* j
  869. /* Input:                                                                                                                                */
    ! M3 F7 {2 \  Z, X% Z% G( j- J
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * U2 B, v# U5 W3 i# M
  871. /*                                                                                                                                                */! }' F" T& S; {: L9 u
  872. /* Returns:                                                                                                                                */
    # z) H) \  ^# a/ z- a. N  g, l! y
  873. /*                Nothing                                                                                                                        */
    5 T9 \' ^- l& V0 n# v, c6 U0 P
  874. /************************************************************************/
    4 ~8 o2 z: {& G. r; _
  875. void Sector_Erase(unsigned long Dst)
    ' z( d4 u3 R* j# `7 G5 q0 h
  876. {1 C9 m0 a) M9 P) q  X" H% E" O
  877. ' [6 V0 v5 |/ l1 B" u# B6 w

  878. ' N  s% e$ K1 U/ W) a3 C7 Q
  879.         CE_Low();                                        /* enable device */
    : |) a" a" ~( y
  880.         Send_Byte(0x20);                        /* send Sector Erase command */$ @, o( e0 @# K
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    0 H, u# T0 t+ }
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ' N6 \% O% ?) [# A( r
  883.         Send_Byte(Dst & 0xFF);0 l) y& g4 k) W4 f
  884.         CE_High();                                        /* disable device */! y* r4 Y: v- q/ |, `
  885. }       
    1 i& |# u/ ^2 P$ \& C3 D' M
  886. * x1 z- V" Q. b1 I% n$ f
  887. /************************************************************************/
    4 g9 E6 s! d3 i4 A) K
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */+ d  _* G5 w  t
  889. /*                                                                                                                                                */7 a3 S2 E0 e1 a2 Y
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */, R7 O' ~8 h' @6 `
  891. /*                                                                                                                                                */+ B( q( A; L- x* V1 v
  892. /* Input:                                                                                                                                */
    6 d8 t9 x/ E! [
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */0 s8 s" P1 X8 j) \) U9 x& N
  894. /*                                                                                                                                                */, y4 p) k" F( m. s* ?" ?5 |
  895. /* Returns:                                                                                                                                */
    * N4 b. ^: W# i. J- ^
  896. /*                Nothing                                                                                                                        */
    5 {. t, u5 @3 q% q- n
  897. /************************************************************************/
    $ g4 t0 C8 n9 a  q; S
  898. void Block_Erase_32K(unsigned long Dst)0 S/ ]2 j! h$ A) _
  899. {
    ( x5 j* a/ M+ y; ]
  900.         CE_Low();                                        /* enable device */
    . a8 w& V" ]( [) f
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */0 B4 w/ I8 r8 |6 c
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */+ p5 _  j* i" T+ g# C. o  H+ `
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ) j6 j0 M% a$ W/ N
  904.         Send_Byte(Dst & 0xFF);
    8 c& ~( H! t' k* K- a' o
  905.         CE_High();                                        /* disable device */
    + @( D- q& M8 V1 G2 d
  906. }
    9 r( H# o  P' j/ c; u" d
  907. 5 X; o6 x; b& U2 q6 |- M2 R- d
  908. /************************************************************************/
    0 B0 T# c% o( A1 t' S+ @' L
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    9 r% U+ L4 J  o0 x
  910. /*                                                                                                                                                */6 a7 i0 U1 m/ C! k
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ) f  a/ U/ r( h6 `
  912. /*                                                                                                                                                */
    5 M1 m7 v. e2 X/ r9 q) J  L  n
  913. /* Input:                                                                                                                                */
    / X& L/ V0 d- ~% I; o
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */* e5 l1 d/ s6 K; N; }
  915. /*                                                                                                                                                */6 I* V8 J$ ]( A* H( ]! t( d; C
  916. /* Returns:                                                                                                                                */
    ) R( h# z/ M6 U" D" v" c$ T
  917. /*                Nothing                                                                                                                        */
    6 G& z2 h8 G. f0 t/ \8 e9 g" ^& M4 F0 K
  918. /************************************************************************/7 \! Q) O0 p( u5 d. ?6 p
  919. void Block_Erase_64K(unsigned long Dst)
    6 I9 ]  c$ i7 d; e) f. g( r: W
  920. {, z2 {9 x* Z9 j! Y5 i! E+ [. f
  921.         CE_Low();                                        /* enable device */
    " l& u; W& Q. r+ g9 q2 |3 S
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */- F6 _( B  [: j- Y1 L
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */  [! o; w3 X4 Q& t
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    * y$ e8 S$ S% h: J& L' R4 ?
  925.         Send_Byte(Dst & 0xFF);
    ' `5 H! ~$ c$ ]" d1 m. M$ D
  926.         CE_High();                                        /* disable device */
    / ~5 G- T6 j, }, o
  927. }
    2 f" X7 W" o9 L( ^
  928. % F1 x. `, w0 H
  929. /************************************************************************/7 ]+ x0 r! y' h3 [! O2 _1 _8 F  x' k
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    9 n- G" `- }& `
  931. /*                                                                                                                                                */# k7 j8 B1 C- M' U0 a& c
  932. /* This procedure waits until device is no longer busy (can be used by        */" a) G; x# J8 Y9 d& v$ U' v
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    ) [, r$ h, L, C9 p
  934. /*                                                                                                                                                */, j: O- z7 y& A: ^* C: _# p! G
  935. /* Input:                                                                                                                                */4 w1 r8 j% ?+ C  O/ I9 X4 {% I
  936. /*                None                                                                                                                        */6 l9 s* v6 N$ R& m! @
  937. /*                                                                                                                                                */3 ~+ L3 [, p* ^  g5 F0 k
  938. /* Returns:                                                                                                                                */7 D6 D" {1 U' @8 A/ z4 f3 D
  939. /*                Nothing                                                                                                                        */# J( B- w" R7 s+ ~) L" M
  940. /************************************************************************/: u4 l1 |7 d* V* F
  941. void Wait_Busy()1 k. U1 e' M$ m1 T2 ~  ^
  942. {
    3 m$ O) x$ u+ m, @& z, e& e: [4 W
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    ) m; t; s8 s$ {" A
  944.                 Read_Status_Register();
    - m% o; q+ D! r* K
  945. }3 X' g. R' V- e+ a# z
  946. ; ?9 G9 F5 W6 [: R. ?
  947. /************************************************************************/4 z' c) `) L: I1 P+ r
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    0 D) h' Y; I. C$ T- Z9 z4 x( x
  949. /*                                                                                                                                                */
    . n% q+ I- n, U* O
  950. /* This procedure waits until device is no longer busy for AAI mode.        */; I& K) _/ ?/ M( I, t. t
  951. /*                                                                                                                                                */5 V! V, B' f+ _" N- F, [
  952. /* Input:                                                                                                                                */
    + S! b0 j: J# k' t$ o
  953. /*                None                                                                                                                        */
    8 e' l  p3 ~; L
  954. /*                                                                                                                                                */
    . n& C2 q# S. A# {/ ]  X% e7 I
  955. /* Returns:                                                                                                                                */0 ]3 C% h1 c* {4 X) h9 y( [
  956. /*                Nothing                                                                                                                        */  F$ P5 g2 G$ V  _) U
  957. /************************************************************************/
    $ O8 Z3 z! Q0 o  {$ Y6 ~  o
  958. void Wait_Busy_AAI()6 E; x9 ]+ ?4 J
  959. {
    # _7 Y( \# k$ O4 {5 g5 s: H1 q
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */. |2 x; o* _# r8 P( n) p8 ]
  961.                 Read_Status_Register();
    / Q5 `% X& H; G  Y/ U: `4 v
  962. }
    6 [6 m* h, r! Y% [8 Y
  963. 9 S9 G* F, X$ T: g+ d
  964. /************************************************************************/
    & k: D  _2 G0 q4 ?$ @, y
  965. /* PROCEDURE: WREN_Check                                                                                                */
    4 f+ G: G8 `4 G6 b8 e
  966. /*                                                                                                                                                */3 P) t0 g% l# c+ O0 z! U
  967. /* This procedure checks to see if WEL bit set before program/erase.        */- H; ?! u, f5 B% S2 d
  968. /*                                                                                                                                                */
    9 i3 B' A* {0 V0 i3 h# g
  969. /* Input:                                                                                                                                */
    " q# i7 q6 L9 Z9 u1 l, [
  970. /*                None                                                                                                                        */* \9 G. J  I1 a) o3 V
  971. /*                                                                                                                                                */
    $ G* d1 ~* I; C( P* ?; o
  972. /* Returns:                                                                                                                                */
      @6 M$ Y: R* e! C7 c
  973. /*                Nothing                                                                                                                        */
    4 N$ ]1 ?  X) P
  974. /************************************************************************/. D3 a% l  G9 j% }! d  B$ o; V
  975. void WREN_Check()7 {3 \7 C6 Q6 u! l/ L4 y9 T
  976. {
    7 e4 A' N! F; j7 ^; L
  977.         unsigned char byte;
    . o/ t+ ]" b, a; C6 ?/ \
  978.         byte = Read_Status_Register();        /* read the status register */
    . T6 H8 q# B5 U8 i9 ^
  979.         if (byte != 0x02)                /* verify that WEL bit is set */( Z9 ~, K: \4 g; ]- l6 E6 S& R
  980.         {4 |, G# u- U2 x$ q7 l+ L
  981.                 while(1)
    % y$ E8 z$ f, Y
  982.                         /* add source code or statements for this file */
    / t7 ~) R  W  \
  983.                         /* to compile                                  */
    2 [9 d" U" s% n& e9 R
  984.                         /* i.e. option: insert a display to view error on LED? */6 O7 p  P  q# e( \7 u' }
  985.                  ' v# p$ O" M% j- u
  986.         }! |. e4 k! c3 u) ]' R" l
  987. }' W. r1 P+ W1 R" W5 h- [3 g

  988. 2 G0 |, _- [) g& x
  989. /************************************************************************/
    ) M' v7 B6 ^2 Z+ M) v* B
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */) D$ D: q& F7 p7 _2 p
  991. /*                                                                                                                                                */. H3 D# N! d  W0 g) W7 S; m# c
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */8 h- z" n( r# ^' W
  993. /*                                                                                                                                                */4 M# n, N( Z; |9 V& y7 h
  994. /* Input:                                                                                                                                */
    2 ?. U7 X0 C$ C
  995. /*                None                                                                                                                        */7 `4 u- ]3 s6 K  _9 q. t( u
  996. /*                                                                                                                                                */
    % ]2 W' T0 x5 }( t" o5 J
  997. /* Returns:                                                                                                                                */5 r" W0 d5 j. _( \. ^
  998. /*                Nothing                                                                                                                        */
    * b4 w7 H. z5 b8 R0 {& K7 ~
  999. /************************************************************************/
    5 b/ u1 n+ B$ h1 W, [
  1000. void WREN_AAI_Check()5 B) L, C! p: E2 J% Q$ j! A1 e
  1001. {
    5 B1 ?/ B/ A7 H3 T$ y3 }) c
  1002.         unsigned char byte;
    % D; U$ s# U* a, {( ?
  1003.         byte = Read_Status_Register();        /* read the status register */
    5 i& F. {! U$ Y$ ~& B: H) q
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    4 y. \' y, X1 u  z. ~: a
  1005.         {  k6 p  E' j, M9 o6 ~* l( j& H
  1006.                 while(1)               
    " e7 I, ~+ J( |
  1007.                         /* add source code or statements for this file */
    9 |1 W; V+ ~; J' I8 k3 i
  1008.                         /* to compile                                  */" a) t! \) D. ~* I
  1009.                         /* i.e. option: insert a display to view error on LED? */
    . \6 D4 p( _+ `+ C3 c2 X

  1010. & B& I. ]* ^  v, g
  1011.         }
    9 j- J  D. ^9 R7 k
  1012. }
    ) U4 V% l. w' |0 A- r
  1013. - E& T% p0 X6 X6 \
  1014. /************************************************************************/
    ) J1 T8 x' \- W: U" |
  1015. /* PROCEDURE: Verify                                                                                                        */
    * a1 F2 u/ g, o- f4 J5 E
  1016. /*                                                                                                                                                */0 R8 ^9 j: @/ b: T3 d
  1017. /* This procedure checks to see if the correct byte has be read.                */
      H( h9 {0 `- p
  1018. /*                                                                                                                                                */
    6 \" ], M9 S7 K* h  M
  1019. /* Input:                                                                                                                                */$ v5 x- n) n$ G$ P. Q2 J" v1 `7 y
  1020. /*                byte:                byte read                                                                                        */5 B  z" \3 ]1 {; x
  1021. /*                cor_byte:        correct_byte that should be read                                        */9 F( j, v; m3 |' A# m" z# o/ y
  1022. /*                                                                                                                                                */; Z  |2 ~( U; k( G9 U- i
  1023. /* Returns:                                                                                                                                */  E/ W( A% ^. R  E  F$ Z
  1024. /*                Nothing                                                                                                                        */
    ; R! c! S# q' B7 P) h: W0 P
  1025. /************************************************************************/
    ' U0 r" R* C* _% V% r
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    6 _7 L2 J2 T1 z" E8 A
  1027. {, U+ R( v+ E3 W! X! H$ v
  1028.         if (byte != cor_byte)
    0 i9 @- z' T& W# D% o3 X1 h8 i
  1029.         {% B8 \/ _: U( v- D9 p
  1030.                 while(1)
    6 N& `5 N0 x$ C! q& d
  1031.                         /* add source code or statement for this file */
    " B9 p3 q. J8 ^
  1032.                         /* to compile                                  */: X. B3 ?+ i7 d" B# L  \% ^# ?
  1033.                         /* i.e. option: insert a display to view error on LED? */- i4 s2 i# p* `6 N" B
  1034.                 6 W0 a) m. D9 M% F( S
  1035.         }
    8 V; c) H% z1 Y" j1 v- f! P" Z
  1036. }
    : T/ x& B+ @6 R: b
  1037.   V4 B+ ^8 y. |& N5 A( W

  1038. ) O; P4 B7 e; h
  1039. int main()1 Y$ V/ @* n% h
  1040. {0 L$ x; t0 Z) g2 v# r5 A* ?

  1041. # h: d5 w$ |3 v) K
  1042. return 0;
    0 Q0 j& m0 A. v0 A5 r# f' t2 Q
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:5 |/ s" Q' n7 C' d
   main()& D; J7 V2 n: `! h' G: |
   里面怎么是空的呢?  w  r( o: \4 r: G; ?5 N; L) E7 m
   发一份给我吧
8 s7 L8 L* `1 P! {8 r  V# Umail:luyijun2005@hotmail.com
. `3 o+ w; e4 l$ G3 _; R5 s; c8 M咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。- W. {8 n) X/ H* l& a( l1 Z

9 F9 V! }* d$ s) e[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
* Y' p8 o3 M/ y4 KEC的代码在哪跑,你看DS的说明,每个EC都不同的。
. z9 c7 M6 [' a! I: AOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?6 y4 z6 a! }( z
上面几个问题是你没看任何东西而白问。7 l; }, y$ ~+ ^; l6 v

/ u! M8 a. D' y至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

% G$ [4 q5 E/ u/ B' a关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
' X8 `8 E3 {" x, [$ @
5 k1 J1 ~! e1 `" V! k0 ]6 C$ k) C关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...% w  x! x- Q0 H
& y& b' `+ t+ M. e1 L8 i
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
5 e6 t6 o# K+ {: L' z似乎要把SPI能support 到最大,这EC chip应该有好卖点3 y0 r9 ~$ r1 F- u1 T
BIOS功能要不要强大,也就决定了SPI Flach的大小$ g  ?! F3 M! r6 N0 o+ L
我是这么想的~让OEM去决定要挂多大!. \/ Y( B) g- M0 L7 t4 N
如果我司有BIOS工程师就好了~哈
/ H  n5 V2 s& O9 CWPCE775应该算很新的东西,来看它支持到多大?
% o* W4 w6 i/ ?. @0 O% X8 ^' E6 O/ G% Y6 H. r
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
( [2 K$ n$ n7 I2 G. n4 h! X其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.) E( a/ V% M' e! b
3 U" h2 a. a! l6 c9 j! X
这份driver收下~希望以后有用到
  b1 @1 A$ C2 v4 G谢谢bini大大
& k0 H1 ~* v9 l
( A8 l  D& |) c0 T( j, g1 e( i很新很新的新手,如有错误请指正 (准备看第二家的EC SPEC)
回复

使用道具 举报

发表于 2009-7-18 15:16:34 | 显示全部楼层
我也有份汇编的DOS下的烧写代码,SST 1MB的 flash可以用。我不知道为什么AFUDOS为什么不能工作,AMI好象没有发送94 CMD下来,AFUDOS直接就说不支持。搞的下BIOS非要自己写个程序,烦的很啊。
回复

使用道具 举报

发表于 2009-8-13 10:59:30 | 显示全部楼层
前端时间小弟也在windows系统下写了一个并口到SST25VF080B的烧写程序......
回复

使用道具 举报

发表于 2009-8-17 16:47:36 | 显示全部楼层

这个函数看不懂Poll_SO()

void Poll_SO()' T3 E* J; n/ [5 {
{
( F, @+ I/ b- B: s+ i& G. |7 e        unsigned char temp = 0;
8 Q9 A% L: ^& t% }. m        CE_Low();$ \( I; k+ Q7 r/ ^( C( T0 v# ~
    while (temp == 0x00)        /* waste time until not busy */8 H) Z/ n: s$ `6 I$ ]
                temp = SO;
) [" M) j/ L2 J& r6 m+ B2 h* \        CE_High();
+ Z% d5 C$ X6 N8 D$ X}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)% K$ L0 {& a* f) B! X/ d0 f
{
! E& Y  H: G4 ^* i) h) }3 R        2 M8 f1 x) h: p! w" w
        unsigned char i = 0;
1 `6 G: z+ w8 u% t        for (i = 0; i < 8; i++)* d# O2 |- ?. |) r' {4 q
        {
' a: l1 c( L  E* j( d$ y% |               
+ @7 g# P# m1 L& d2 P& i                if ((out & 0x80) == 0x80)        /* check if MSB is high */
" n0 L: f1 I  @' s                        SI = 1;6 s; E! Q" t3 B% u9 a0 W, @
                else7 X$ [& j: L; p  Y; k3 W, X  ~4 o
                        SI = 0;                                /* if not, set to low */
% U/ k+ R4 o/ N  ~  X1 g7 @8 s' U 问              SCK = 1;                                /* toggle clock high */- j5 y1 O$ K1 d; \4 h. M2 \
   题            out = (out << 1);                /* shift 1 place for next bit */
0 S% r  v; H2 R# x3 \& M- M" t7 Q+ x: [( S                SCK = 0;                                /* toggle clock low */' Q5 t* b5 l) m! [
        }. B2 I- [. f) S3 {% f3 @* r
}
( j8 u* y0 E$ t; n- _& O) I, O 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-5-16 06:52 , Processed in 0.071288 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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