找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54763|回复: 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
    ; u$ z4 U" ~. p% ]3 K! f5 d, Z
  2. % N1 u' L' }. G) ~
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    6 M4 ?8 }4 p' ]- M2 J4 F

  4. 0 h6 c% l, I6 R1 W5 ~
  5. November 4th, 2005, Rev. 1.0' e3 @. S# ~+ [2 n2 T' b
  6. 6 I& a- J: M6 u( N" W& r
  7. ABOUT THE SOFTWARE5 S9 M1 W; J$ b8 n' m, J0 N
  8. This application note provides software driver examples for SST25VF080B,, q& E* q: d) D1 U/ q
  9. Serial Flash. Extensive comments are included in each routine to describe
    - Z$ S& [- p' j! P/ ^
  10. the function of each routine.  The interface coding uses polling method
    ) v$ }/ |. Z5 W# f' y
  11. rather than the SPI protocol to interface with these serial devices.  The5 V$ g0 Z! C  h! O0 ^! d  ?" X8 _
  12. functions are differentiated below in terms of the communication protocols
    0 s$ I  j/ x9 \/ T3 A
  13. (uses Mode 0) and specific device operation instructions. This code has been . \) Z! O7 m" N5 I; N( S) H
  14. designed to compile using the Keil compiler.1 D; e# l8 I5 x0 k" D; P

  15. - C( X* `' v- U  c% ~9 v

  16. 9 r8 m6 Y- S4 f9 [& V
  17. ABOUT THE SST25VF080B
    9 r, E. T8 F4 _$ B# C' f$ C* Z. g0 A

  18. 4 H( I9 S! ?" c! x
  19. Companion product datasheets for the SST25VF080B should be reviewed in 8 o5 @2 \; i+ W. g  l& [: @7 T# t* z
  20. conjunction with this application note for a complete understanding
    % Y$ }* }: m4 |
  21. of the device.3 p8 x  t# D2 s( D; }. d" i  |

  22. : B7 _' Y$ q4 O4 U) z9 x
  23. * V+ ?. t& K' P& ?' x
  24. Device Communication Protocol(pinout related) functions:
    ; O" G8 V! |( S9 ^# h- e3 ]
  25. + u% \  ^, T% m9 F
  26. Functions                                    Function4 m* d+ J5 Q- a7 ~% r% A0 @
  27. ------------------------------------------------------------------
    ( j, y2 k9 v& z1 h3 m
  28. init                                        Initializes clock to set up mode 0.6 i: G/ n% {: o( K8 B5 A
  29. Send_Byte                                Sends one byte using SI pin to send and
      [7 _. U6 k) Z% z3 Q, U
  30.                                                 shift out 1-bit per clock rising edge
    6 m1 f+ @! k% z- S5 [: A' X9 J  Z
  31. Get_Byte                                Receives one byte using SO pin to receive and shift   m  z: D0 P% c; L
  32.                                                 in 1-bit per clock falling edge
    5 D) F5 Q, O; l; j
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    . d9 C* M/ w1 j( D4 }  D4 s
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high- Z7 p* O2 V. Z$ F2 h
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    " }. k' d; S8 I( ?
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    4 Z* u- q5 ]! o8 _" E
  37. Unhold                                        Unholds the serial flash! ~. c. ]- O( ~# i- Y$ g, F
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    " q, o5 x$ m: \* c. }: o
  39. UnWP                                        Disables write protection pin
    " s1 C6 S! M4 P2 t0 \9 v9 m
  40. 2 Z4 B: g1 D1 @6 P
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code0 T3 h$ l8 ^1 l# u& Z
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your0 }9 q6 V5 k9 @, x& s) G7 ?
  43. software which should reflect your hardware interfaced.          
    $ \6 [, H4 E9 E. Z7 T2 C

  44. * w" S" q6 T" D0 F. g5 `' R

  45. 2 y' n# b6 B& C
  46. Device Operation Instruction functions:
    % L& I4 |+ k- R0 F. z% `' E! ?

  47. 0 B0 q4 p: t+ @
  48. Functions                                    Function4 v, [1 Q0 c5 d- q. t% O. }9 g( I
  49. ------------------------------------------------------------------. Q$ A* a5 X: [( n4 c7 T3 x% B5 z
  50. Read_Status_Register        Reads the status register of the serial flash
    1 H4 k% C6 S9 o4 j) z- Z+ t
  51. EWSR                                        Enables the Write Status Register, _7 J# r0 {- R/ B' E
  52. WRSR                                        Performs a write to the status register0 H! D" D% X6 |; f( m
  53. WREN                                        Write enables the serial flash5 D7 x. w, K. F' k7 c; [5 m6 j1 ]
  54. WRDI                                        Write disables the serial flash. Z. ^8 d6 I4 q
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    1 r+ t; p8 ~" C; U( p
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    9 B( j( C& Q! o' c% D- h! \0 G6 W
  57. Read_ID                                        Reads the manufacturer ID and device ID* E/ P% v7 e0 Z3 v2 d$ O- e
  58. Jedec_ID_Read                        Reads the Jedec ID
    + O& h- w5 [3 T' t' c: Y3 J
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    1 Y' F/ B* I- m
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency). R$ X6 |3 J9 V2 Z
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)5 A9 }& c* D$ g3 }9 _* ^& c
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    4 a$ d+ a+ `: N2 r% B$ O2 N4 |
  63. Byte_Program                        Program one byte to the serial flash
    & A" m3 s7 _, ?2 V% Z& {
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    & w' Y+ a% s5 k2 U( n6 T
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation7 {9 l1 `' b9 ~( b) k7 ]
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY4 q' y: x: ~. Z/ M( b
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY' a9 [2 h+ {; f7 H- \
  68. Chip_Erase                                Erases entire serial flash+ K( _% Z' X; Y3 W$ {5 X
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    / x! C/ T7 O2 I: F" t
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    3 r3 [( t7 }2 h* O% v
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash# ^) m: Q+ W0 y; E) r0 x3 ^: @( s' R6 p
  72. Wait_Busy                                Polls status register until busy bit is low. [# }/ ?* }; r5 m$ k: V
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming: N+ h; z' T: }- o8 z2 l# T
  74. WREN_Check                                Checks to see if WEL is set
    : z* I2 z0 L: K) Y- X
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    & W* h1 o9 X$ h# r/ L3 @

  76. / k: q$ S( m- C  Z

  77. + U8 _9 }! x: X! P: d1 h: P
  78. * Y& y& T0 b/ O" `% E3 \* [
  79.                                                                      2 T; f2 w/ j/ g3 `+ i
  80. "C" LANGUAGE DRIVERS 3 e# ?' n& T/ x

  81. 3 K4 g+ [4 B, w, Y
  82. /********************************************************************/6 r6 D+ x! h2 j# @
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    - _& v+ F/ H8 U$ p
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    9 \' A( P2 C  I% t  V5 x
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    5 l7 @4 @+ R' A2 [( v
  86. /*                                                                  */: t6 {6 k  O( F% T
  87. /* Revision 1.0, November 4th, 2005                                                                          */   / v4 u( {/ J/ |3 k. U( Q
  88. /*                                                                  *// b* I/ }; k  W6 U! C9 s
  89. /*                                                                                                                                        */. Y- n0 z' K0 Q
  90. /********************************************************************/6 V/ {7 C( @5 d5 T

  91. 7 ~' x& B; ]! c
  92. #include <stdio.h>
    # X7 N- y+ T" Q" N, ?
  93. #include <stdlib.h>
    4 y: M) ?4 C8 _2 ^
  94. 9 H, b& R/ G2 l8 B! G3 \. c
  95. /* Function Prototypes */
    7 f: b7 V# G: @6 X) [4 V" ]
  96. " }- h# ]( o/ l# }' W7 F$ Z4 i
  97. void init();
    , n8 J0 r  N8 k8 y1 _
  98. void Send_Byte(unsigned char out);7 j0 f; @7 z- K* U& L4 ^0 I
  99. unsigned char Get_Byte();& o( c% Z1 j2 P. B3 n
  100. void Poll_SO();& t5 o- T8 c! f, X! Z
  101. void CE_High();, e( V8 O% _8 o8 ^4 v5 G7 z
  102. void CE_Low();, G& J/ N2 J! z! Y3 \" P/ r6 [
  103. void Hold_Low();
    ; c1 n6 q( e5 Y0 n& T
  104. void Unhold();: e4 S: O& e. o
  105. void WP_Low();- v1 ?/ k3 q  T
  106. void UnWP();' R% X, i" `$ y' c1 w& Y
  107. unsigned char Read_Status_Register();  O- K+ K7 O$ ^9 K' Z! z3 f( r
  108. void EWSR();  o& G8 K+ K( h8 n
  109. void WRSR(byte);4 ?9 a$ S7 t, J# e( T2 \' [2 F/ ]
  110. void WREN();
    0 S8 z# X0 @% o: E
  111. void WRDI();
    6 a; ^$ M* `$ Y
  112. void EBSY();# Q9 h" f1 c) x; e2 p3 B  m
  113. void DBSY();6 T) t7 i1 t8 D5 ?$ y
  114. unsigned char Read_ID(ID_addr);
    4 v- ]1 I5 C' @! N; a/ \
  115. unsigned long Jedec_ID_Read(); 3 H7 U" m+ a$ A/ C& H( o6 Y+ D
  116. unsigned char Read(unsigned long Dst);
    + U' z) A3 n0 J" z2 w4 Y
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);  k/ t, p* ~7 d, J% ?. I6 V- v" Z2 e% x9 N
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    0 k4 ~  B" p2 e: ^9 D8 w% q" Z3 N) x
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);0 \" Z! b( j' ?. d0 T9 u, G
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    3 Y+ K0 H5 J# a
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);, D! O# a( L* u" z
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);% o- W5 u6 z2 E3 E/ @, U! ?
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    0 ]  v& Y1 s  @' u* v% w
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    . U( F* a; i8 v' @) T2 I8 W
  125. void Chip_Erase();
    2 I) N; r. t: |
  126. void Sector_Erase(unsigned long Dst);( ?# C' c. P1 ~6 p: C
  127. void Block_Erase_32K(unsigned long Dst);
    + [8 f5 m: B( D5 x  a
  128. void Block_Erase_64K(unsigned long Dst);
    ; b8 i7 ?- p/ n1 k
  129. void Wait_Busy();% P# I0 y8 n3 M9 u! R( x
  130. void Wait_Busy_AAI();
    6 Y( j; U  y) X/ f
  131. void WREN_Check();% U9 W1 K/ J7 M4 G; u
  132. void WREN_AAI_Check();
    - s/ x" p4 ?# L# r$ L. Y
  133. 7 Q( z$ |, |2 L" _) o' d7 C
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    5 [  N9 c5 m1 w% ~
  135. 1 v5 i+ X8 `; w- r
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    ) _7 P; `& r. D7 J# R
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    . A' Y* `0 \5 O- D* _

  138. * }% L( w, |2 Q3 m
  139. /************************************************************************/
      @9 ]! Z. a. X" g; }) h/ B
  140. /* PROCEDURE: init                                                                                                                */7 g' t3 P% _" b( }! j* A
  141. /*                                                                                                                                                */% ?8 ]! @6 @: p& B( H3 B; Y
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    ! h. h# ~0 v9 a8 S, H4 ?
  143. /* setting up mode 0.                                                                                                        */
    ( x8 [2 L0 N* Y; [$ o. Y
  144. /*                                                                                                                                                */
      B1 U6 q2 {- @8 r: \9 M
  145. /* Input:                                                                                                                                */3 t8 R4 G; _: c- b
  146. /*                None                                                                                                                        */! [3 Y9 U/ J7 K; G& U
  147. /*                                                                                                                                                */, l# C* L5 b- P8 k
  148. /* Output:                                                                                                                                */
    7 k: c4 ]8 o2 _. f; r
  149. /*                SCK                                                                                                                                */
    & U! `' x  T4 n  b7 ^' I
  150. /************************************************************************/( @; M3 y5 ]; C9 V6 Y" t6 o
  151. void init()3 v7 {0 f- P# O! A
  152. {
    * ~" S2 X1 j# v/ M9 H
  153.         SCK = 0;        /* set clock to low initial state */
    , R, s5 G! O( h( P* ]: c9 E# c
  154. }9 ]" R8 V4 R) c

  155. 7 U! Q9 y0 @" ?  _4 P
  156. /************************************************************************/
    4 j+ h/ O" H; {9 }
  157. /* PROCEDURE: Send_Byte                                                                                                        */- X3 }! x# r% b
  158. /*                                                                                                                                                */
    ; }+ U  Y# S$ I; t
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    7 O5 \. u. K9 l, M+ s
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    1 F1 v4 U& O$ W$ P; E4 B# [
  161. /*                                                                                                                                                */# k/ l& }$ M6 e: t
  162. /* Input:                                                                                                                                */
    8 [  f+ J* D9 |. r
  163. /*                out                                                                                                                                */' s9 ~5 E/ t. g  m5 T* M3 X
  164. /*                                                                                                                                                */4 g+ f  `% s' @9 x# E6 e
  165. /* Output:                                                                                                                                */. o, u+ r" J3 p( ]0 [. P( p$ {
  166. /*                SI                                                                                                                                */
    9 J+ ]7 i, }5 }3 i5 d
  167. /************************************************************************/
    ( `: F& Z/ T3 i  D) [1 M# C) Y
  168. void Send_Byte(unsigned char out)
    . ~( v- Q2 [1 e: s& r- ?( j
  169. {1 D* Y% Z* k+ g6 h+ Q7 p
  170.        
    0 R, Q0 k# Q! u' @' x9 q
  171.         unsigned char i = 0;
      |6 j: d5 y, F( p: U
  172.         for (i = 0; i < 8; i++)2 C" |7 E( q& A
  173.         {
    / d9 W9 o+ q% _6 y) a+ |1 q. X9 y
  174.                 ( \% \+ J4 z( c* _
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */$ |% L8 E+ o1 y4 m# C
  176.                         SI = 1;/ q7 Z: y( J) ^+ F* d! G& |5 e
  177.                 else
    ! |+ |/ z, N& O# H
  178.                         SI = 0;                                /* if not, set to low */& J; B8 o, d8 [: ?- R& G- }
  179.                 SCK = 1;                                /* toggle clock high */
    7 l  S. \% A& r1 I6 E0 b; O: G
  180.                 out = (out << 1);                /* shift 1 place for next bit */' f! g- Y- `0 ^! g+ {/ x: H
  181.                 SCK = 0;                                /* toggle clock low */
    - ^* L% h8 a9 u. T8 s1 n$ C. y- ?
  182.         }
    0 H# D7 c6 |% ^5 y4 k+ }% a5 I: k
  183. }" J: a0 B. Y0 X5 s( Z& Q8 h( A
  184. $ P% M, y* ]0 u6 e+ v! u, f
  185. /************************************************************************/
    ' N; t, y6 g" m
  186. /* PROCEDURE: Get_Byte                                                                                                        */9 ?1 U; \. Z- v& y
  187. /*                                                                                                                                                */& o6 q3 t4 d8 W6 D4 \
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */1 [6 A6 }( a4 R' n5 f8 K
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    # q$ h2 D4 n. J# `" G
  190. /*                                                                                                                                                */7 D# c9 k; N/ K9 S( }
  191. /* Input:                                                                                                                                *// G  `9 @% v6 R5 w+ @" h
  192. /*                SO                                                                                                                                */7 P2 P! Y+ _: [+ K$ g' a; G
  193. /*                                                                                                                                                */9 c8 E& v+ G" A
  194. /* Output:                                                                                                                                */6 e3 j- W4 S% `, [- Z  {- T
  195. /*                None                                                                                                                        */
    ) H& e6 c) w; {; }
  196. /************************************************************************/
    9 J" P$ M9 O! i3 `9 ?
  197. unsigned char Get_Byte()8 ]$ i( U. t% Y6 ?7 c$ ~
  198. {
    * o' o& M# K0 k1 n& l' N/ {
  199.         unsigned char i = 0, in = 0, temp = 0;
    4 {+ p' E- S" Y. ^- S' x
  200.         for (i = 0; i < 8; i++)
    ' d$ l$ x6 \; V. c, x
  201.         {  n9 G, P4 R( d0 A$ d- P
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    ; r9 ^) l  p: H. J
  203.                 temp = SO;                        /* save input */  K) g9 X1 f% I+ c. J
  204.                 SCK = 1;                        /* toggle clock high */
    9 b! S0 e! v0 [* i( N
  205.                 if (temp == 1)                        /* check to see if bit is high */
      z$ |8 I4 s0 `; Q( \# @
  206.                         in = in | 0x01;                /* if high, make bit high */
    , E+ ]; J( ?4 B# J. c

  207. : @# Q; h6 |! D: z) f
  208.                 SCK = 0;                        /* toggle clock low */' w# _+ x  X8 K5 D4 F9 d( L
  209. 0 D- y2 z& }$ P! ?: Q/ y
  210.         }
    & F7 t$ X  x, Y; ~) s! Z( }) T
  211.         return in;
    : I; T: F, b. c& H  g5 p- h- R
  212. }
    + }# ?' G% X+ q; n* o. o( V# H/ c

  213. 6 c# ?6 H" p4 l# Y# ^2 i# M
  214. /************************************************************************/; T, K0 l7 N: ~0 y
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    1 u9 A1 c1 q( O$ N- `/ U
  216. /*                                                                                                                                                */
    1 _* u& E: x: w1 }& Y- H
  217. /* This procedure polls for the SO line during AAI programming                  */
    5 A  q9 E% }6 h- [; S7 K7 {& L
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/& j& W3 l, N- A
  219. /* is completed                                                                                                                        */
    ' n) b9 ]+ }; v$ M* r0 [
  220. /*                                                                                                                                                */9 e( O0 s6 v! J  |/ x
  221. /* Input:                                                                                                                                */8 y0 ?, ~! ^" U  d) X2 J9 |* y# H( R  U
  222. /*                SO                                                                                                                                */
    4 G6 l, z: X$ I
  223. /*                                                                                                                                                */
    + n- ^$ L$ [8 m  i; c
  224. /* Output:                                                                                                                                */$ I- Q9 A: x2 V+ D
  225. /*                None                                                                                                                        */* g  t8 O& @, q6 o1 F3 Z
  226. /************************************************************************/
    6 k! Q. f3 t2 c) z6 F
  227. void Poll_SO()
    * R, K" A, g  X4 n  _/ q
  228. {3 J* k# E" J4 b9 ]
  229.         unsigned char temp = 0;4 e7 R# E+ w) O1 V" D. A
  230.         CE_Low();! J4 r7 n6 b3 t" C6 ^$ F: `! Q' r0 G& r
  231.     while (temp == 0x00)        /* waste time until not busy */
    4 G, ^, l% _" d0 i3 F) X5 ~4 v
  232.                 temp = SO;
    $ @/ P: ^/ L7 z- V5 A
  233.         CE_High();- Y2 v  W, p7 i5 t0 @& T
  234. }
    . i0 Q) l1 f$ U9 T2 v- N% m

  235. , ]8 W( q- S5 n9 Y4 G4 h
  236. /************************************************************************/7 `% ?1 [2 G' @0 j
  237. /* PROCEDURE: CE_High                                                                                                        */; t* Q1 C9 f/ q7 t/ _
  238. /*                                                                                                                                                */
    # ^" o% Q& p8 S5 O, W+ Z' ^
  239. /* This procedure set CE = High.                                                                                */& `- {- E* J5 M# m
  240. /*                                                                                                                                                */
    7 q* ]1 s; o, c7 c
  241. /* Input:                                                                                                                                */
    + _% d3 [. U6 X
  242. /*                None                                                                                                                        */& m5 a! C* k$ m! `% s2 N
  243. /*                                                                                                                                                */
    9 i) ~' T% c1 I
  244. /* Output:                                                                                                                                */, |1 S3 y8 C. w( R0 A
  245. /*                CE                                                                                                                                */6 @2 K6 b- I) W" t: i/ h) X
  246. /*                                                                                                                                                */
    $ ]  h6 l% C* U4 I# U
  247. /************************************************************************/" O: e! T# j0 O% z- @0 Y
  248. void CE_High()
    , o4 B' y: @$ `( S" S/ V. j$ h
  249. {! k8 [3 ~; p8 N3 B1 k
  250.         CE = 1;                                /* set CE high */
    9 I! y0 e! c5 H2 N! q, U5 d% F
  251. }7 O& a# k" f5 o9 [2 a5 c1 i

  252.   u3 ^1 _) _9 [, H; d1 ]
  253. /************************************************************************/# i2 ?+ b5 X( }( I) f
  254. /* PROCEDURE: CE_Low                                                                                                        */
    , L+ d' r5 a/ a
  255. /*                                                                                                                                                */0 f2 v4 C# Y4 b! _6 r) i; x
  256. /* This procedure drives the CE of the device to low.                                          */
    % u" U$ x8 G2 M' H
  257. /*                                                                                                                                                */
    2 \/ a, A/ |& C! D) N
  258. /* Input:                                                                                                                                */: _9 E' U/ W2 e7 Q
  259. /*                None                                                                                                                        */; c7 C- j& A9 N) S, @5 }2 @
  260. /*                                                                                                                                                */8 |9 u4 J, T( `+ [( e
  261. /* Output:                                                                                                                                */4 ]; J; Y1 H  T5 m/ @" o
  262. /*                CE                                                                                                                                */8 H* w8 e8 {  `; d& B6 C" C
  263. /*                                                                                                                                                */  i' H/ V- b! |$ [5 {8 I; M
  264. /************************************************************************/7 K! G1 g4 w( k1 d
  265. void CE_Low() ) B, j8 G0 O5 x/ _- u! M3 G2 L
  266. {       
    ! u2 m) Q% P8 g6 f7 g# R% U& l* {
  267.         CE = 0;                                /* clear CE low */
    ) m2 }& \! n7 Z3 E2 W6 A" w
  268. }1 k0 s* y; F6 H( ]
  269. ! [; U2 }1 n  n3 \
  270. /************************************************************************/
    , A) w' t( Y/ i! \
  271. /* PROCEDURE: Hold()                                                                                                        */
    2 ?& p4 i8 Y4 c" y$ ^8 f, e! h4 n$ Q
  272. /*                                                                                                                                                */! C2 |4 P; H' e" \& F' a
  273. /* This procedure clears the Hold pin to low.                                                        */
    # r$ _' a* P: I- D# B! w
  274. /*                                                                                                                                                */, M3 C0 Y1 W4 D" [: C. c% g
  275. /* Input:                                                                                                                                */) ?# L" n# w/ k. {3 h& L
  276. /*                None                                                                                                                        */
    % m2 c' b, O8 Y* r( ]7 K: a
  277. /*                                                                                                                                                */
    ( O; @( Z  \' c- b
  278. /* Output:                                                                                                                                */
    . a0 K% v* l) F) Q
  279. /*                Hold                                                                                                                        */$ b7 L% g. Y1 d  D; h4 y/ H
  280. /************************************************************************/
    - T% h# D3 x4 y  D4 c2 O# O+ F* r
  281. void Hold_Low()
    8 w# Z& C+ i. h' }  ]4 r3 g
  282. {
    ! [: h. |  j% u3 F
  283.         Hold = 0;                        /* clear Hold pin */
    0 B, q+ L9 c& Z9 o) e2 L( v
  284. }
    . |2 J8 L+ q2 D, Y! C

  285. . O" Z; l5 o3 g) n
  286. /************************************************************************/9 C  P% r; I6 L' }* t5 j, C7 x
  287. /* PROCEDURE: Unhold()                                                                                                        */
    7 h# E9 t* ^& C* B
  288. /*                                                                                                                                                */
    ; k5 P" D0 J" f- n
  289. /* This procedure sets the Hold pin to high.                                                        */
    ) O% h9 G% U0 \' ?! U: w
  290. /*                                                                                                                                                */7 ^: b2 ^5 Z" x# o
  291. /* Input:                                                                                                                                */" U+ T/ X2 x' }5 |0 U- ]. G4 {
  292. /*                None                                                                                                                        */" R3 z5 ^' L5 W' U
  293. /*                                                                                                                                                */# ~, ^* q0 C1 K5 l9 N% o
  294. /* Output:                                                                                                                                */
    % n  V  @" d7 o5 N' C
  295. /*                Hold                                                                                                                        *// o: t) o! J- z- f- o" \/ [
  296. /************************************************************************/
    + Z8 h# j! D. [7 O3 S" V0 C  u
  297. void Unhold()5 D5 d; j2 ]9 q  d4 w1 s& M
  298. {/ f+ Q; k6 y9 x2 m0 V
  299.         Hold = 1;                        /* set Hold pin */
    . b. M1 M) Y' B) W3 U
  300. }- i5 `6 p* A" C6 l  D1 k* v$ x

  301. 7 F" o: p3 z; e! t. J1 |
  302. /************************************************************************/7 L  r: S& K) w; k( O" O+ u0 S( H0 t
  303. /* PROCEDURE: WP()                                                                                                                */) K$ c) p: }3 O( o% n
  304. /*                                                                                                                                                */5 Y' ?, s  Y/ q, f0 |  H# ^$ Y
  305. /* This procedure clears the WP pin to low.                                                                */: U( r# J2 c" K+ @; E
  306. /*                                                                                                                                                */7 [: e( v8 Z( k! |
  307. /* Input:                                                                                                                                */* Z+ `6 `: H: G, X
  308. /*                None                                                                                                                        */  V+ @9 w: v  H* V
  309. /*                                                                                                                                                */2 Q7 a2 u' m, N* X
  310. /* Output:                                                                                                                                */
    , }8 M8 g3 A$ @4 G! j
  311. /*                WP                                                                                                                                */% |; P6 r  h; [% \' W. D! Z
  312. /************************************************************************/- L3 f4 c& V: w8 `
  313. void WP_Low()" y6 r) m1 D0 R$ ~) v6 }
  314. {
    5 \/ \4 A$ M: x6 y! O% g" Q" z& b$ }
  315.         WP = 0;                                /* clear WP pin */
    3 z! l' B4 ?# y, z
  316. }$ {# W, ]5 C) Z* ?0 b
  317. / |) s/ S* M) |5 A& n! S9 g' D" }/ S+ Q
  318. /************************************************************************/: L8 V* z3 h% i4 _$ X5 b& g) f
  319. /* PROCEDURE: UnWP()                                                                                                        */8 k4 c# |$ V& z# y( W; s
  320. /*                                                                                                                                                */# u+ R( w' ^& J/ T
  321. /* This procedure sets the WP pin to high.                                                                */
    ( t" U3 \& J* D. n6 Y
  322. /*                                                                                                                                                */- o. e( U8 t/ c7 E
  323. /* Input:                                                                                                                                */7 s" f+ z( b4 D, w
  324. /*                None                                                                                                                        */# _- w( l/ {) ]! O' f
  325. /*                                                                                                                                                */0 X5 j. Y, _$ r) C% y8 r# O
  326. /* Output:                                                                                                                                */
    " t8 p1 c3 J: V* ^
  327. /*                WP                                                                                                                                */% F' D, X0 O+ ]% o$ W4 X
  328. /************************************************************************/
    7 N5 L) L3 \" x. f
  329. void UnWP()
    - ]) s. c8 m5 k: R5 g
  330. {
    1 f/ l6 b1 }% F
  331.         WP = 1;                                /* set WP pin */
    5 T. _1 \0 x; E) Z
  332. }" V& o# v" }% I, y* }- J) }

  333. 2 F- X8 s$ J! J3 K& U  Q
  334. /************************************************************************/
    6 k, O7 u* z& q# u$ _
  335. /* PROCEDURE: Read_Status_Register                                                                                */$ o, F4 h6 z5 j0 M
  336. /*                                                                                                                                                */
    9 j# N3 W2 s! t. b3 {( \  z
  337. /* This procedure read the status register and returns the byte.                */" M. ?9 [1 \- t
  338. /*                                                                                                                                                */
    8 U8 S2 ^5 n  T2 p: _( }7 Y
  339. /* Input:                                                                                                                                */
    $ a& Q$ h  y% v6 p* K: M: _
  340. /*                None                                                                                                                        */
    0 D: B* B9 \8 L7 y) @& G) z
  341. /*                                                                                                                                                */' R- x8 Y# F2 p$ o2 Q7 ~7 I
  342. /* Returns:                                                                                                                                */
    + ]: ]2 P+ j2 g* b
  343. /*                byte                                                                                                                        */3 t7 r" i# r8 {& \& t% t
  344. /************************************************************************/8 W9 v! c/ p. T- U0 C& n! t
  345. unsigned char Read_Status_Register()" j( y. `  e# V: k1 z
  346. {' A8 u; J* u& U5 s7 J" H
  347.         unsigned char byte = 0;
    ( L/ n- i: t8 ^
  348.         CE_Low();                                /* enable device */
    ) I" w& \' j: i5 ~3 O4 u
  349.         Send_Byte(0x05);                /* send RDSR command */
    % l( Z8 a9 C$ {# y
  350.         byte = Get_Byte();                /* receive byte */
    " s$ h- P0 ^' F% O' m: N8 c9 N
  351.         CE_High();                                /* disable device */
    . H  m, W# R: V7 `
  352.         return byte;/ e$ x2 }) @: _
  353. }- k4 S* n6 Y; x/ q( W- O, C$ C' d8 L
  354.   y# z7 B6 R$ [8 C5 P
  355. /************************************************************************/
    9 ^$ d0 t) w; ?+ @/ X( y6 s
  356. /* PROCEDURE: EWSR                                                                                                                */: g7 \9 f$ g9 ]' p& s1 ]
  357. /*                                                                                                                                                */# _  v  J: [  R: I# V) |
  358. /* This procedure Enables Write Status Register.                                                  */2 z  ~6 P/ d# I( G
  359. /*                                                                                                                                                */  M" d% x# t$ O2 y; ]
  360. /* Input:                                                                                                                                */  o* D( N7 Y/ [( `5 w
  361. /*                None                                                                                                                        */" L0 U& P! i3 x4 I+ p2 `- w( {
  362. /*                                                                                                                                                */
    : |. x( O6 Q$ w$ {+ S7 P/ r  b
  363. /* Returns:                                                                                                                                */% y+ P9 l. W9 Z: B  a' c# v
  364. /*                Nothing                                                                                                                        *// G5 i- }% w9 N( n0 M. Q* N7 o
  365. /************************************************************************/2 h" k( r! D/ A' M/ N' {
  366. void EWSR()
    " {5 Y+ i: w% P6 g# _) Y# @
  367. {& Y. f5 x3 R0 l$ y8 D& _5 J
  368.         CE_Low();                                /* enable device */. k: ]- N. b. p5 K7 W3 ~( X4 \
  369.         Send_Byte(0x50);                /* enable writing to the status register */; t( Q* b9 B3 E, J. l0 w7 \9 s" I
  370.         CE_High();                                /* disable device */
    ' P0 U) r! |. g3 X: E
  371. }
    - e+ V) i6 k% ~$ A# H, G0 ]! F( }0 D

  372. & j- e/ P0 _; p1 v9 I0 t+ m
  373. /************************************************************************/
    $ K3 |! c5 Q0 W+ o" W
  374. /* PROCEDURE: WRSR                                                                                                                */( K9 }% c& X& n2 u1 q; Q
  375. /*                                                                                                                                                */% F4 `* k' ~8 r: \  ^# d' e
  376. /* This procedure writes a byte to the Status Register.                                        */
    * h" d  r5 q1 P3 s5 {: w
  377. /*                                                                                                                                                */1 y6 Z, v0 K3 e# w  @) n
  378. /* Input:                                                                                                                                */
    / L( t1 ~2 q8 k4 I. n; }
  379. /*                byte                                                                                                                        */8 e. ?" w6 @% `+ X
  380. /*                                                                                                                                                */& v' _, e4 o( \* i  w. V6 j7 y' h
  381. /* Returns:                                                                                                                                */8 W* z2 Q& P& |2 Z& o
  382. /*                Nothing                                                                                                                        */2 n$ _: ]7 z( L5 O1 N1 [
  383. /************************************************************************/0 r8 {- Q2 T: M4 f- |
  384. void WRSR(byte)
    $ r# x8 k* Z. s0 X- _
  385. {' i' C, |" H7 l4 ^* y2 g, b9 ?
  386.         CE_Low();                                /* enable device */# n/ ^! i1 W/ c; Q4 b: ~
  387.         Send_Byte(0x01);                /* select write to status register */
    0 x; ?7 B; V1 f, }+ P
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    ! w1 Z$ }) H8 W. E
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    + o2 G# t1 U! n4 ?
  390.         CE_High();                                /* disable the device */
      V, w1 ^8 _4 \3 A! n
  391. }( M# f1 E7 I! f

  392. : n7 t% u0 a4 J
  393. /************************************************************************/" j& }# ]' o1 g+ X. _# H; x
  394. /* PROCEDURE: WREN                                                                                                                */+ N" d: L8 W" h: \
  395. /*                                                                                                                                                */+ i) N; ~* j8 u1 r
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    ; u$ u8 J% _% b- s" x; F8 J
  397. /* to Enables Write Status Register.                                                                        */( m: i* Z& ~! q4 R
  398. /*                                                                                                                                                */
    % d1 Z( {- O7 B; R7 N
  399. /* Input:                                                                                                                                */
    3 o9 s8 r9 Z; \9 @- I
  400. /*                None                                                                                                                        */+ Q7 P+ H. [1 N' j2 Z
  401. /*                                                                                                                                                */5 L- c: B+ q! c' [, {8 h
  402. /* Returns:                                                                                                                                */
    5 A" E; _5 P$ L2 X# |0 `* G9 m
  403. /*                Nothing                                                                                                                        */
      p& `" w; {. J# m0 b4 u0 s
  404. /************************************************************************/+ h' Y+ ?$ V7 E8 n1 E5 _
  405. void WREN()
    ' P8 L$ w' ?6 ~
  406. {" _/ w5 `  c2 }8 @- b& y$ ^5 l
  407.         CE_Low();                                /* enable device */
    3 S% P4 @" d3 ?( W8 u. N4 |; p
  408.         Send_Byte(0x06);                /* send WREN command */, H$ h7 \! @" C3 K8 a- d, Y' j$ G
  409.         CE_High();                                /* disable device */
      I3 o! m  T0 }* k
  410. }# }6 z; ~' m5 r. o6 y

  411. % }4 [1 ^7 U5 M; H
  412. /************************************************************************/" ~  B$ B1 K" z4 S9 e
  413. /* PROCEDURE: WRDI                                                                                                                */
    0 u4 k/ p0 y/ o4 |+ |- m) \0 M8 [- s+ N
  414. /*                                                                                                                                                */
    & u3 m( Y' c) t* t. b6 _
  415. /* This procedure disables the Write Enable Latch.                                                */0 J8 Q. p. J/ U7 N4 F
  416. /*                                                                                                                                                */- I, m- Y3 n+ _  y3 l
  417. /* Input:                                                                                                                                */
    1 a5 W" \# w6 F5 u( O# ]( r2 {
  418. /*                None                                                                                                                        */
    # H( Z! H. f" \7 _- h
  419. /*                                                                                                                                                */1 m1 o6 V+ |7 E/ m6 I7 X
  420. /* Returns:                                                                                                                                */
    / K2 _( O0 M+ m- @$ v4 _
  421. /*                Nothing                                                                                                                        */2 f. }- H: A4 x
  422. /************************************************************************/  s# w5 Q" g$ E7 K
  423. void WRDI()
    $ e. P" E0 l, n! c$ N
  424. {
    # X. f  o( H4 N3 I1 ~# q7 [; t
  425.         CE_Low();                                /* enable device */% Y: l9 B3 H/ i
  426.         Send_Byte(0x04);                /* send WRDI command */
    9 j0 F6 i  {/ [) l$ A
  427.         CE_High();                                /* disable device */! B* S) W, N% b4 G5 Y
  428. }
    1 k& @( Y3 s3 n

  429. 0 p2 K6 n) M# X* l; p
  430. /************************************************************************/
      }% h6 F/ P+ z# p0 W3 r: h# y
  431. /* PROCEDURE: EBSY                                                                                                                */
    3 K) Q1 t, Q: |5 m0 Z8 Q
  432. /*                                                                                                                                                */0 ~! v: m% G, l3 Y) l" c# h; X4 F6 H
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */& @4 F9 A2 _0 d. v- x& t& L
  434. /* programming.                                                                                                                        */: i/ k2 J! e( a2 O" R' o, A
  435. /*                                                                                                                                                */+ D' H1 |# l4 h( O) j( V+ `1 d
  436. /* Input:                                                                                                                                */! {7 t( a/ n7 b
  437. /*                None                                                                                                                        */
    , ^% L' |7 G1 X" |* L. E7 W
  438. /*                                                                                                                                                */1 G# b8 ?- T; b7 U4 A
  439. /* Returns:                                                                                                                                */
    / E! j- I% h6 L" @" O" w2 \) g9 d+ R
  440. /*                Nothing                                                                                                                        */
    ! O( x1 B4 e* j4 R; f: {
  441. /************************************************************************/1 t* Z4 M, Y2 H, ^
  442. void EBSY()! @1 [6 G) n( Q
  443. {
    ( C8 y# `5 [8 N4 ?
  444.         CE_Low();                                /* enable device */* w: Z. i. C9 M! f9 C1 c
  445.         Send_Byte(0x70);                /* send EBSY command *// b! x: l3 v  z) D& o
  446.         CE_High();                                /* disable device */: U5 U+ n5 P* u8 z
  447. }6 e. B% U2 z+ q3 W
  448. ; o& V8 q7 t% N0 I
  449. /************************************************************************/
    1 ?( Z; N7 U( D, r: @' P
  450. /* PROCEDURE: DBSY                                                                                                                */
    7 ~1 F8 |% R2 O1 K4 z1 f9 \
  451. /*                                                                                                                                                */
    * T2 d, a6 `  c7 L8 F! `5 a
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
      ]0 o2 u! j/ ]0 Q
  453. /* programming.                                                                                                                        */" S: k4 Q% N4 [# F
  454. /*                                                                                                                                                */
    - O" P( w6 O8 \7 |
  455. /* Input:                                                                                                                                */
      S+ I* ^- w& N- P8 n! a! ~% C! K
  456. /*                None                                                                                                                        */
      g1 c9 F4 _' N/ j
  457. /*                                                                                                                                                */1 h6 s1 _) t; f4 v( k; N3 ]! Z
  458. /* Returns:                                                                                                                                */0 m5 J8 L) @0 E; Q/ z8 X
  459. /*                Nothing                                                                                                                        */
    6 y! [7 B* u6 D. U; G7 j4 j
  460. /************************************************************************/" a! v9 v2 R- l7 R% [9 ?5 u
  461. void DBSY()6 z& I$ ?) H1 z7 d6 b
  462. {( f! `+ {' Y& M( E/ W' ~
  463.         CE_Low();                                /* enable device */$ Q6 n$ w$ G( M6 L
  464.         Send_Byte(0x80);                /* send DBSY command */" R4 u1 w- P0 |' v/ k
  465.         CE_High();                                /* disable device */) M% o) c6 g  i' h4 m
  466. }
    ! z4 S7 _, w! D( v+ G( T. T

  467. * B6 y4 A8 ^8 _. J. a
  468. /************************************************************************/
    # i. L/ C" z& Y( ?
  469. /* PROCEDURE: Read_ID                                                                                                        */
    3 d# z7 b: m7 b; l) J# ?) F; \4 b
  470. /*                                                                                                                                                */
    + r6 m% u6 x" g+ X! l9 d
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    ( u, s, x" H2 @# R6 j* P( B
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    / o+ v! G! _: I/ m
  473. /* It is up to the user to give the last byte ID_addr to determine      */1 h+ `" s5 |/ K! i- @
  474. /* whether the device outputs manufacturer's ID first, or device ID         */, g5 c2 H9 g* m4 \0 H* r
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    ; C. J+ k; F) i& d# W! y
  476. /* variable byte.                                                                                                                */) L$ e" c4 }; x( t
  477. /*                                                                                                                                                */  k% D- I( I- [8 S! \7 }  n% c
  478. /* Input:                                                                                                                                */
    ( G; `2 L5 G$ v7 J2 I# Z" Y
  479. /*                ID_addr                                                                                                                        */
    ; v, H2 Y" D; Q) ?' c4 Z! k1 \
  480. /*                                                                                                                                                */6 g: P4 z. b. e& F! M
  481. /* Returns:                                                                                                                                */6 M0 V; I3 T; _: ]- W: r
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */0 D/ e$ C. o6 z9 G8 y: t9 {
  483. /*                                                                                                                                                */- T9 [" h1 U+ \+ f# }) w
  484. /************************************************************************// A: I( _7 I. l/ d
  485. unsigned char Read_ID(ID_addr)- l! d5 E' v& n% ]( K' ?9 C
  486. {* \" f3 S/ T+ X. H
  487.         unsigned char byte;
    . F9 z( [% Q8 f6 W* M! t5 P# _
  488.         CE_Low();                                /* enable device */
    2 q$ b2 G; Q6 A8 L
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */- G; H; ]. O* z
  490.     Send_Byte(0x00);                /* send address */
    9 |0 l' p: t! p) F" \& ~! K* q, `
  491.         Send_Byte(0x00);                /* send address */) \' l! z3 _$ G' @+ c0 m
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */5 L7 o+ ?4 j3 @% r
  493.         byte = Get_Byte();                /* receive byte */8 }$ C7 T' ~3 U3 K; n
  494.         CE_High();                                /* disable device */5 L6 w% l/ j, [% D2 v! V) h
  495.         return byte;
    ( y! k. @. I# C6 S) f% _
  496. }
    6 ?6 @$ A3 v8 ?. t' k  w
  497. 6 R6 m; K7 p# t& d
  498. /************************************************************************/
    ) S. l" W3 |+ |
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    % N0 W0 Q/ ]7 I- |; M( I6 \& `
  500. /*                                                                                                                                                */8 y2 _: T6 }1 T4 M( F
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */5 a8 G; e" A5 J& ^* ^+ x% X  X' ~
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    : n- H2 y4 t/ i( p& Z: }
  503. /* Please see the product datasheet for details.                                                  */
    6 E- u: Z8 }" {
  504. /*                                                                                                                                                */
    2 q1 h% Q* q: C- e! c
  505. /* Input:                                                                                                                                */
    ( B6 F: R: J7 U. @5 a9 D2 Y% t' Q  h
  506. /*                None                                                                                                                        */
    . B& L+ u! S3 F- e- y* l
  507. /*                                                                                                                                                */1 e; ~: B: H3 ^) r! r
  508. /* Returns:                                                                                                                                */3 g6 r$ ~- X# K4 {$ R7 J
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */* j6 Z/ b. V, I) g0 o
  510. /*                 and Device ID (8Eh)                                                                                        */
    & K3 Y  r! S5 B2 S% F: _& h4 V
  511. /*                                                                                                                                                */2 p. s8 ^+ C" u7 w% \
  512. /************************************************************************/
    ( v# s( y4 ?  R8 F$ `; }5 x# ]
  513. unsigned long Jedec_ID_Read() 8 W0 J) i& W9 t' E( @3 ~" D, t
  514. {! d' m3 K, {3 P3 J7 r
  515.         unsigned long temp;: K+ `% i/ D- q% T
  516.         $ b" O8 M: x) L7 G8 h3 |0 V4 {. Q! A& b
  517.         temp = 0;, I6 F, ]: d% v" o/ n* a3 l

  518.   z& ^# P8 _5 z: x7 t; l2 q6 W
  519.         CE_Low();                                        /* enable device */
    8 }9 |% O$ l1 e! ~! W% u
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    ; V" y% V. m5 K* C
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */0 J0 L8 s( T7 Q& A: x! ~1 ]
  522.         temp = (temp | Get_Byte()) << 8;       
    / v! x. K, K0 S/ {, l% M" g! Z
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    1 M' N) D& J: O2 A; X7 {
  524.         CE_High();                                                        /* disable device */& E9 w$ J' w0 `8 V1 W

  525. ' T4 q6 B' Q( t+ z/ e: H
  526.         return temp;
    7 A$ c. v" I1 y8 e  A- N8 X
  527. }
    ( ^; s9 r) t2 v6 s: a

  528. # ^+ C5 O. ]3 u: m) a, h
  529. /************************************************************************/
    ! G/ P# h' J5 ~8 L
  530. /* PROCEDURE:        Read                                                                                                        */# f9 h8 ?! [) P2 F1 A4 g
  531. /*                                                                                                                                                */                " A# D: k) Z1 |8 U: N3 F4 u
  532. /* This procedure reads one address of the device.  It will return the         */9 n) q6 S4 G+ V" O" T
  533. /* byte read in variable byte.                                                                                        */
    9 t) D4 u- C8 i1 u& l
  534. /*                                                                                                                                                */7 D8 I& [5 X0 j/ Y* }; R" p7 K1 p! v
  535. /*                                                                                                                                                */
    * @# T* e- l+ }7 X7 J
  536. /*                                                                                                                                                */
    9 ~0 m. z/ Y2 L, r0 v/ Q* H0 {
  537. /* Input:                                                                                                                                */9 e! \; y4 r( Y; o. @! d; t9 |7 _
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */" i0 j) N2 b+ Z+ o9 V/ ]  a
  539. /*                                                                                                                                      */
    * ?, ^+ b# b/ L) f5 h
  540. /*                                                                                                                                                */
    + t9 O# \* J; f! A
  541. /* Returns:                                                                                                                                */
    . _- X- D9 b, f1 L! _
  542. /*                byte                                                                                                                        */; d7 O( h+ n7 c" [
  543. /*                                                                                                                                                */
    7 c& `3 d" }+ d% i/ M  _' G- H) D( _
  544. /************************************************************************/
      S6 \# Q& z% x5 T8 j: K9 N
  545. unsigned char Read(unsigned long Dst)
    2 h0 O7 P" O: v+ r# T1 k/ Y" v
  546. {' S$ O( x6 S; R" ^+ M& [
  547.         unsigned char byte = 0;        * t- q( Q! D3 t5 z6 f7 ]

  548. 4 v/ ~4 X! @$ H" v; G8 w, W+ P
  549.         CE_Low();                                /* enable device */
    9 h7 y! M  T" e0 z
  550.         Send_Byte(0x03);                 /* read command */
      c% h- b# d$ I) H
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ! U3 D' M1 J8 ^) [: O
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));; e& |/ b, J" ]" O2 I
  553.         Send_Byte(Dst & 0xFF);
    0 `( F1 c. d) Y4 |
  554.         byte = Get_Byte();
    / M  Z" Y, ?' x/ X7 a
  555.         CE_High();                                /* disable device */
    * T& B' c9 E: Y9 k% b/ i
  556.         return byte;                        /* return one byte read */+ l; V, T& S1 W: k3 s
  557. }+ e, O) U3 q* }3 ]

  558. / g4 l2 Y( G) Q
  559. /************************************************************************/& k4 U, t0 ?. U' e6 B) V
  560. /* PROCEDURE:        Read_Cont                                                                                                */# a' I! T- v9 J# N0 ]
  561. /*                                                                                                                                                */                8 T0 {! X0 J  S; q2 C' N9 q4 c/ t
  562. /* This procedure reads multiple addresses of the device and stores                */
    7 _7 i' G+ c( Z3 }0 `' Y: n
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/6 y, k+ Q; X9 A9 N
  564. /*                                                                                                                                                */
    * B! H4 R6 f$ z. m0 w
  565. /* Input:                                                                                                                                */5 [" H- p( X: S* p
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    % [7 Y! v. h9 z, @- [
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    7 Y( d1 C; J$ G. G& k1 Z- u
  568. /*                                                                                                                                                */, n& d% m7 y$ @7 H2 |. t" {
  569. /* Returns:                                                                                                                                */
      |& y- Y; m6 _+ o5 X4 ]; q
  570. /*                Nothing                                                                                                                        */8 a9 Z# V% \1 q/ ^6 h
  571. /*                                                                                                                                                */
    ! w' _  L/ K: K/ I- Q5 L- `* _
  572. /************************************************************************/
    - l$ c) Z8 Q3 N: G1 k" K( D: _
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    3 P! f8 }; L" V9 I0 t: E1 v
  574. {# q( d* o9 C( ]% m' l
  575.         unsigned long i = 0;
    ) |0 G. H8 L! Z/ ?
  576.         CE_Low();                                        /* enable device */+ l! c  z4 N& q: p) t
  577.         Send_Byte(0x03);                         /* read command */
    : k( K" T6 _. ^3 r
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */. g* D* i8 _9 n8 x
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));/ q9 z4 |9 _( }
  580.         Send_Byte(Dst & 0xFF);8 X  E  F# n& k1 @% C$ T* f5 ]
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    - t+ U& o2 \8 q/ K: ~7 A
  582.         {
    + z  l3 e; w+ Z* G5 Z
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */! W5 {. G' s! T) N3 L, l
  584.         }
    % a( ?; G% j+ b1 w$ K" b6 o
  585.         CE_High();                                        /* disable device */: ~0 v1 T% k! u3 H: ]7 d, E

  586. ' Q" I$ `3 e! Q4 }5 t7 t
  587. }
    $ o. y! y( W% j3 ~

  588. 3 D2 s, p# t3 q/ ^
  589. /************************************************************************/
    1 F0 Y8 S+ M" q4 \8 C! Y
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    6 p( r; P' e9 N( W/ j3 \
  591. /*                                                                                                                                                */                4 W: K" |0 @2 j7 ~( f1 }
  592. /* This procedure reads one address of the device.  It will return the         */
    4 z( X- V$ N; ?5 Y- l& ^3 m, {
  593. /* byte read in variable byte.                                                                                        */- z/ y; ~( S- |6 b
  594. /*                                                                                                                                                */3 H$ `$ f+ _! Y5 B9 C* [, a
  595. /*                                                                                                                                                */" D/ G" j" A/ p# X$ v
  596. /*                                                                                                                                                */
    0 I% O& L4 U7 Q) z6 X
  597. /* Input:                                                                                                                                */
    + Y' r: Z8 Z: U8 O$ z
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */- Q7 i) `( p( ]; t- q9 r9 h" \
  599. /*                                                                                                                                      */
    . `, a5 h1 t  d
  600. /*                                                                                                                                                */
    6 F, s% \7 U! u  |1 c# I9 [
  601. /* Returns:                                                                                                                                */
    + l1 w( i& A# h8 [% P
  602. /*                byte                                                                                                                        */+ O) x# w5 \3 h2 m$ V0 [
  603. /*                                                                                                                                                */8 {: _2 j! ?6 |- E: y% d! A( v$ ^9 U/ D
  604. /************************************************************************/
    - u3 F/ g7 `) A: m/ W
  605. unsigned char HighSpeed_Read(unsigned long Dst) 8 u( i8 V/ G# u; L7 R8 b4 S& Z
  606. {
    1 [( C$ u8 x4 l  B6 Z
  607.         unsigned char byte = 0;       
    1 o- y8 {& s8 N. q5 L/ x5 C3 R

  608. 2 [& {3 N4 t5 w3 w
  609.         CE_Low();                                /* enable device */
    " ?$ i+ j  D$ ]2 w* [% ?/ Q
  610.         Send_Byte(0x0B);                 /* read command */0 A* G: H1 D' K9 V) |/ |
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */( }- X! _. {3 t6 N0 w* g
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));" g0 D0 r" y' i- t7 [3 v: Q
  613.         Send_Byte(Dst & 0xFF);
    ! g2 Z# @( r% u4 y
  614.         Send_Byte(0xFF);                /*dummy byte*/
    ! o2 w7 U0 |" ^5 o6 z
  615.         byte = Get_Byte();/ c: ^: Z' V* c4 D8 y' a
  616.         CE_High();                                /* disable device */
    , @7 f- C/ \6 q# Z" n
  617.         return byte;                        /* return one byte read */
    - a8 D) t) R& {' i# _. v
  618. }
    0 X+ [+ c" ?9 q/ m: b6 X

  619. " J% `% X) `+ b# E  \8 O; \* [
  620. /************************************************************************/
    & a6 [3 C7 f% S3 g& y  ~3 v7 T
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */$ b5 H: V" K* e# x( P
  622. /*                                                                                                                                                */                $ L4 \- E' i' p% b
  623. /* This procedure reads multiple addresses of the device and stores                */
    3 }( b7 H; [7 ?/ j$ P& l
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    9 l) R  J" V3 S$ i( h
  625. /*                                                                                                                                                */% K; W& z+ y2 \. _$ i
  626. /* Input:                                                                                                                                */+ {  K$ v8 `! F$ k
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */* O% R( D0 K8 Q% o+ o/ J4 P
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    . H/ J0 ^& u& J3 J- N6 B
  629. /*                                                                                                                                                */
    ( l) q6 E$ t* @% z! [9 ~$ m6 Z
  630. /* Returns:                                                                                                                                */* Z* @) E, H# [) {1 s
  631. /*                Nothing                                                                                                                        */. U& t2 J/ J' P: \1 [
  632. /*                                                                                                                                                */
    , }5 n" F3 @% ?/ L: G; l! w" Y
  633. /************************************************************************/
    7 x6 ]3 s: |' I4 y" u1 O& V% B
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)) _3 h5 E  T. @& s( D: P. A" t
  635. {9 Y8 p+ ^2 p  K8 M% c' N' m0 e
  636.         unsigned long i = 0;
    2 _. f3 L4 a; }
  637.         CE_Low();                                        /* enable device */
    $ N. A4 c& s8 Y% @5 \) v! `& i
  638.         Send_Byte(0x0B);                         /* read command */( V$ {& r. J0 c1 M7 [5 Q6 i$ L
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */, N- ^/ C; S: |1 J2 \$ F) g
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));5 M6 ?$ g! S) N5 c
  641.         Send_Byte(Dst & 0xFF);
    5 m/ L% [' C! F. [: j: |
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    2 [$ J& b7 T* T/ r6 o: ~/ G& G( o
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */8 _* A( K/ K# j9 _, {+ F" C
  644.         {
    4 a4 n  B  d* \
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */. V1 C) K$ e4 K" I- p5 V" z4 \0 o- P
  646.         }
    , `$ i% z& Z4 G8 I
  647.         CE_High();                                /* disable device */
    ' ~$ ?# s% ?/ @0 D7 e4 I) x- d4 v
  648. }) {2 s# d! o' c: ^, j. r

  649. 1 s1 ?' i8 k; x3 a* r& ?
  650. /************************************************************************/  \5 e0 X* z; m9 t5 |
  651. /* PROCEDURE:        Byte_Program                                                                                        */, y( d- J# O& a4 \
  652. /*                                                                                                                                                */- t' X- o# N) F( X! G
  653. /* This procedure programs one address of the device.                                        */
      ?; d- X- l1 V( s
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    1 s* [/ P/ F; E  s$ c; J6 A
  655. /* block protected.                                                                                                                */  a& g) s& H" q# D+ t# |
  656. /*                                                                                                                                                */
    2 A+ v- r1 ]0 @# c6 j3 ~0 c
  657. /*                                                                                                                                                */% ]6 x7 h1 T( g; M+ b; b) J
  658. /*                                                                                                                                                */
    ; b4 G% s" W( @8 H
  659. /* Input:                                                                                                                                */
    7 z6 [2 j. j, [" b2 C. N$ _
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * V1 W- e* |5 k7 X
  661. /*                byte:                byte to be programmed                                                                */
    " Z$ ?/ u2 e! l" Z9 i- t
  662. /*                                                                                                                                      */
    $ C: M+ K) t2 H$ T
  663. /*                                                                                                                                                */
    2 [% e7 k' w/ I/ K$ z5 E
  664. /* Returns:                                                                                                                                */; b5 S& P* R: `" C* y. l
  665. /*                Nothing                                                                                                                        */. x8 ?7 A  a) E0 ~0 }7 {
  666. /*                                                                                                                                                */+ H1 M, k5 a4 Y* ~3 X
  667. /************************************************************************/5 W' I* |% H2 j4 s5 k
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    " H4 @' m9 J: Y
  669. {. I; T! o7 E7 h5 }6 d: M. j! S+ K
  670.         CE_Low();                                        /* enable device */
    9 ^$ Z% V+ _! X& v
  671.         Send_Byte(0x02);                         /* send Byte Program command */* G2 ~- {) ]5 j7 C5 l: r1 r  P
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */7 x* Z# n# Y9 z# R* [
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));
    : Q* |6 A6 T8 \: J9 B9 u
  674.         Send_Byte(Dst & 0xFF);
      K% Q0 p1 w$ o5 {
  675.         Send_Byte(byte);                        /* send byte to be programmed */7 A0 u  ^8 n) m7 Q8 _+ j# t
  676.         CE_High();                                        /* disable device */# h4 N4 W3 u& ~
  677. }3 r- f1 T3 @" |. X% `/ t. K$ t

  678. 7 G. e& K0 ^6 ~1 D8 P
  679. /************************************************************************/4 X  N& p5 }. K" f2 v
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */# _; ?/ p* ]0 h+ r7 K' @7 F* T5 ?
  681. /*                                                                                                                                                */
    3 x, Y5 |% q/ v1 a5 T& z0 r$ {; r
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/, J, y/ X( |7 h1 e- ]( S" |
  683. /* the device:  1st data byte will be programmed into the initial                 */2 q3 ^; X: d5 C9 E" T; M9 I* L: E
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    ' ^: ^, T7 L/ H2 n1 ^3 u
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    4 F5 i+ p$ N+ `- I! y2 Q
  686. /* is used to to start the AAI process.  It should be followed by                 */# x) M. Q% S% l: }, n
  687. /* Auto_Add_IncB.                                                                                                                */
    0 O! f$ s  v  X  B% V- L6 n" ]+ B
  688. /* Assumption:  Address being programmed is already erased and is NOT        */6 y" }7 z' k- L$ A: j8 p
  689. /*                                block protected.                                                                                */) d! E$ |1 P& s3 }% H9 X+ e- L
  690. /*                                                                                                                                                */
    . ~5 e' d3 ~0 B' D# d8 G
  691. /*                                                                                                                                                */
    ( ?6 k) l* W% z" Y5 T* ?* c
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    7 }4 G, Q& }' `, Q9 K; Y  D
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */8 S5 P1 l$ o. A. N8 |
  694. /*         unless AAI is programming the last address or last address of                */
    & U5 x3 Z% G/ @* ]' f4 }" |
  695. /*          unprotected block, which automatically exits AAI mode.                                */* g- P% I, u& e0 H/ O4 i
  696. /*                                                                                                                                                */+ s4 `) v1 g$ d
  697. /* Input:                                                                                                                                */9 ~# `" s2 i( M% l" p
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + I4 B; L) c2 f. Z. T) f& e" C
  699. /*                byte1:                1st byte to be programmed                                                        */% j! w: z4 n8 y. W
  700. /*      byte1:                2nd byte to be programmed                                                        */
    * y8 o4 D, ?" a2 r& q
  701. /*                                                                                                                                                */
    * l, g0 y+ \3 P! E  F$ s
  702. /* Returns:                                                                                                                                */6 m- K7 p: E4 t  F$ L8 O6 h) l
  703. /*                Nothing                                                                                                                        */
    / Z' @, Q) o6 f2 ~' J8 Q" t
  704. /*                                                                                                                                                */
    1 E3 U& h4 p/ Y7 ~; g9 Q
  705. /************************************************************************/9 a+ u: h' S0 p4 T" b- z0 {
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)2 W: m+ ^2 V! ?2 H
  707. {: R  ?/ l, }0 e, q/ m& [: S* }
  708.         CE_Low();                                        /* enable device */
    ( A+ |  H# r  Q: b; H5 I
  709.         Send_Byte(0xAD);                        /* send AAI command */3 f/ k' x7 K3 y( G0 x4 D
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */( C5 c6 K$ g1 O! F9 |
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));; H2 R1 ]$ N4 V1 N  p
  712.         Send_Byte(Dst & 0xFF);
    , X2 o  c8 _& i5 y" p/ U! C; n# L
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    9 a0 h+ ]0 _: Q+ V" e, X
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */* _+ L) l/ t5 _+ U) t+ T+ s$ K
  715.         CE_High();                                        /* disable device */
    1 |8 z/ [: Q) J/ h# x
  716. }  o; m7 S6 M! S  r) \
  717. % |# F2 t, A3 E
  718. /************************************************************************/
    5 ]' {) M' w+ U4 b* W
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    6 }  K. C2 i& w7 j* y
  720. /*                                                                                                                                                */
    # z0 n) x' U6 J- s! ]3 f
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/7 }& S, N; s# i# e$ N0 q  r
  722. /* the device:  1st data byte will be programmed into the initial                 */3 x" D/ T0 p5 `4 x: |
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */6 f. v5 D5 I: S# z, N5 O
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */: X3 h7 A8 v2 F/ @3 U; }5 ?& ~% o
  725. /* is used after Auto_Address_IncA.                                                                                */
    ) U8 I2 H* l: ^* f7 f- c
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    + u: i2 `9 [" H
  727. /*                                block protected.                                                                                */
    . a. x. X& B  B
  728. /*                                                                                                                                                */3 V: o# f( \& c$ W1 i  Z
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */" k" V- f1 w. O/ F1 F' @* H8 a
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */3 Q+ g+ r+ E+ o0 L* I9 ~6 z
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */$ \4 a! z- V6 ]
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    / T2 N+ V: \# K% J. o
  733. /*         last address of unprotected block, which automatically exits                 */
    : N2 s2 }; O: @0 r7 P
  734. /*         AAI mode.                                                                                                                        */9 `0 i! R: p3 X5 z! V, Y
  735. /*                                                                                                                                                */
    ; ^' l5 E0 U. [! M, f5 _0 @: C
  736. /* Input:                                                                                                                                */0 D/ q( v5 D# |
  737. /*                                                                                                                                                */
    1 B' L+ W8 G; V6 Z
  738. /*                byte1:                1st byte to be programmed                                                        */. P, A% P1 y0 h8 O
  739. /*                byte2:                2nd byte to be programmed                                                        */) H$ ]3 N9 W; r! z/ i  H
  740. /*                                                                                                                                      */
    ( ]# O+ H/ w7 e3 M
  741. /*                                                                                                                                                */, w* u. r  l# O' F
  742. /* Returns:                                                                                                                                */" ~6 s3 B- g/ J) q/ T
  743. /*                Nothing                                                                                                                        *// ?# J. }8 j. L# Q+ C9 A
  744. /*                                                                                                                                                */
    - Q' t1 y* K! f8 L, }9 C6 E) v% @/ h
  745. /************************************************************************/
    4 m, K; k- D3 y4 s! [* ~( M, g
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)5 f  X  e5 J, S6 K9 E! |
  747. {
    2 h0 b! e; F7 @, @' c
  748.         CE_Low();                                        /* enable device */
    ' V* D1 E" R+ a- u9 m, d
  749.         Send_Byte(0xAD);                        /* send AAI command */( @* d" }6 h! \6 `+ h, H
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    # ^' W) Z" h4 _% T" b1 A1 Q
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    & @5 v# \; z% [( h  e1 r1 ^
  752.         CE_High();                                        /* disable device */
    3 Z6 P! Z5 M. T! G" k( ]' b, x
  753. }
    0 i1 U4 M3 M/ \4 |& U

  754. 4 }+ E: ^  @5 b3 m
  755. /************************************************************************/
    * S( \+ d5 f: }% x/ |9 B  W9 T6 \
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    $ e( ?9 F; Y5 C
  757. /*                                                                                                                                                */5 J4 |* O, A5 `3 v: }! a
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it *// F  d5 ^0 g. D2 Y3 P$ M3 `9 x% w
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    7 C" ]* ?6 |1 \7 n( B. o
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    + l, X* X. N% i2 r
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    0 y5 N9 G5 Q7 g2 E& e3 @! T
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */  g# ?" F/ q; o( j4 c$ S7 [9 w
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    - Z, q9 C9 H  S, C" k  V
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */% g' @3 {$ g, ~
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    3 _; \1 O; z3 A2 O+ O6 R  i
  766. /*                                block protected.                                                                                */; }% b+ n& E' f4 h. [8 J0 V
  767. /*                                                                                                                                                */
    ; S" I6 |1 T0 L/ G$ ^' b& z
  768. /*                                                                                                                                                */
    - j: T+ N' z# j% n% V
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    % U# S7 W2 @- o/ o+ N
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */% q, A$ J% ?: d+ G, [
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    2 |8 c4 b2 t% P) D3 }6 j3 p( P  S
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    3 K# n4 v9 t( X( g; H& t
  773. /*         last address of unprotected block, which automatically exits                 */
    ; T% J9 W" i+ g7 T  Z( i+ L
  774. /*         AAI mode.                                                                                                                        */: T0 G) r! P" w4 ]) n9 _) C
  775. /*                                                                                                                                                */
    ' {( J/ M2 @) |1 N# i6 G2 D; A  N
  776. /* Input:                                                                                                                                */" B% {* e) a& R" q/ z9 K
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */2 y' Z# Z: [" v
  778. /*                byte1:                1st byte to be programmed                                                        */
    3 L3 G7 _1 O* F' T4 a- s- L3 [
  779. /*      byte1:                2nd byte to be programmed                                                        */, j( [  ]/ U# e3 X
  780. /*                                                                                                                                                */( a3 l, j; M9 V% v* ?' ]5 |8 \( z) @
  781. /* Returns:                                                                                                                                */) v9 R; [* c' _3 N
  782. /*                Nothing                                                                                                                        */5 l( A# e# h% |4 u" f
  783. /*                                                                                                                                                */4 m% K4 C4 b* H/ @' r
  784. /************************************************************************/
    9 A8 t  ]# F  r! O1 q" i+ z
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    6 [9 Y4 @6 s& B' k2 ~
  786. {
    6 h8 {0 E) e* K6 H/ M9 Z
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */       
    ( x3 b! f7 K7 `, J- c, S' b3 x. G

  788. & i/ ]- N2 [9 n9 D" j  \! c" u
  789.         CE_Low();                                        /* enable device *// Q0 A5 G/ A9 O5 v
  790.         Send_Byte(0xAD);                        /* send AAI command */4 N8 o0 _" j) i+ U: C0 P
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
      C9 H* z' X; _4 I
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - o* s" V3 {+ l
  793.         Send_Byte(Dst & 0xFF);
    8 O2 V& I0 V+ N0 W3 N( I: H- U
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        * Y, f# [  s% B8 R; D
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */! y$ M6 Q0 z% R7 P8 O
  796.         CE_High();                                        /* disable device */
    , n( k- a7 X; Y
  797.        
    , H: l7 ]0 p4 D" y+ o
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    ! O+ ~: n( C8 q/ A$ J% R

  799. ( `9 C0 }6 B; @% F3 F
  800. }1 A4 l( r4 x6 q8 e- Q1 p: b
  801. 9 [+ a3 P7 w& A$ j
  802. /************************************************************************/6 ?0 y5 K% A( Q$ `2 }0 @' \3 V
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    % H; e+ I( A/ k
  804. /*                                                                                                                                                */" J$ Y2 P4 P. y* L/ r  ~2 k
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    # l: F8 f1 ]4 ?: ]3 i0 B& S6 y
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    & O/ J$ Y( h3 p* N
  807. /* AAI programmming is completed.  It programs consecutive addresses of */- T1 @3 r2 Y/ w+ F% m1 a
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    $ ]0 N/ o; r+ L( u7 [' ?
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    0 j( G: N7 @/ c7 Y6 r
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */% w/ z# Y! T1 r3 @- i
  811. /* used after Auto_Address_IncA.                                                                                */
    & B# ?4 H, {; n/ `) ?
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    ) A  M8 T3 H' v0 l
  813. /*                                block protected.                                                                                */  E9 \* ^4 k5 A7 o3 ]
  814. /*                                                                                                                                                */
    / R  Y5 `' ^) s: a& A
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */" Y; h# Q; p) j
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */, c; R+ i( {" O$ B: |) Q1 e
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */' d1 S; t  L# U. ~
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    & G% I$ C+ e) d8 C2 G' e& Q# @
  819. /*         last address of unprotected block, which automatically exits                 */
    3 k7 e& ]  D8 g5 I$ I1 N0 ^
  820. /*         AAI mode.                                                                                                                        */# Z4 ^: |' Q5 z8 P' _0 i
  821. /*                                                                                                                                                */
    0 j$ g0 D6 }3 y4 f  [
  822. /* Input:                                                                                                                                */
    / ^6 y9 U% X5 _6 b8 F
  823. /*                                                                                                                                                */! B" `3 W0 [5 W* H
  824. /*                byte1:                1st byte to be programmed                                                        */2 ~9 v9 u6 l+ u& a) W/ C* a
  825. /*                byte2:                2nd byte to be programmed                                                        */
    2 y! l' B# J9 ]3 Q! x
  826. /*                                                                                                                                      */$ N, D0 y0 H$ g$ `% \9 D# O
  827. /*                                                                                                                                                */
      L" u' ]( G* k
  828. /* Returns:                                                                                                                                */7 O# r7 Q! O  o7 G' a- l* F
  829. /*                Nothing                                                                                                                        */) ~. [* j. W/ x0 W
  830. /*                                                                                                                                                */
    - f, ?% c9 y& \7 }' B
  831. /************************************************************************/
    " I. Q3 z2 B; X
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    ( y" g/ E" @* U4 W
  833. {; ^9 {) k) g3 t- I( y2 I% E1 m
  834.         CE_Low();                                /* enable device */6 ^' w' R6 n3 X. }: }& }3 P6 j
  835.         Send_Byte(0xAD);                /* send AAI command */
    ( z, P2 Y, T( `' d
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    + l5 H2 C, ^) x% [5 e( U+ Y. |
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */7 g3 d' R7 L' k# @% `/ |; W: ?* \
  838.         CE_High();                                /* disable device */1 R5 K( }2 E/ c3 f7 l$ d: P: M) ^  a' D

  839. ; H% S  V5 v% ]; b$ k* v
  840.         Poll_SO();                                /* polls RY/BY# using SO line */% a8 r8 s5 n3 \# {

  841. % ?$ z' n' m$ [( g
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    6 R" L; S0 w) [' f) v. ~: H
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */) j, m9 s/ x2 p7 t) p
  844. }
    ' I- G9 q' i2 I; ~. p# ~
  845. 8 D7 `# s9 f( g/ O" y
  846. /************************************************************************/8 }% [4 s0 f% W- f$ w" j
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    4 Q# ?9 h& ?! S8 M. e/ @% {. h
  848. /*                                                                                                                                                */& `$ n! i# [1 S
  849. /* This procedure erases the entire Chip.                                                                */2 ]4 c+ u- N1 x/ U
  850. /*                                                                                                                                                */: v& I- `) J; n
  851. /* Input:                                                                                                                                */
    ; y; |7 m6 L& A) X! }
  852. /*                None                                                                                                                        */
    / c# r) v* ]0 j! u, m. Q& b% C" z
  853. /*                                                                                                                                                */5 l$ D8 ~5 o4 z: x  {
  854. /* Returns:                                                                                                                                */
    ; X7 E2 E9 ~; f6 X% ?6 R) u
  855. /*                Nothing                                                                                                                        */
    , b8 j. ~) r. R
  856. /************************************************************************/
    # h" L% M$ i( e7 N- c1 ^
  857. void Chip_Erase(), r  I+ e  \5 T# `) C/ \
  858. {                                                / O8 j4 C9 r6 L; G: R/ ~- ~1 Z
  859.         CE_Low();                                /* enable device */$ M8 d; s2 m# o* S' k/ ~# v
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */, B+ l! j$ I, l4 V" x
  861.         CE_High();                                /* disable device */; o; F1 B% |8 F* I1 B' r% X
  862. }5 b  f8 Z& m: H, @* u- O5 h
  863. , J' c0 R! ]% A& r' k2 c& _0 d
  864. /************************************************************************/3 m& i8 }: `5 Q2 [3 Y
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    0 P2 b' S+ |, G  A% R  {4 e  x! m! r
  866. /*                                                                                                                                                */8 }* W7 P9 Q4 Z) o* [
  867. /* This procedure Sector Erases the Chip.                                                                */
    6 I7 \6 t& v* }" L5 a! _
  868. /*                                                                                                                                                */- ~7 O4 y0 t& u: z. N
  869. /* Input:                                                                                                                                */) h5 o+ q) P) G9 B$ }* G$ S
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    " F3 `+ b, g/ c* _! r# q4 ~
  871. /*                                                                                                                                                */
    & I0 c# ?7 N6 c" a( e1 V
  872. /* Returns:                                                                                                                                */3 N" k- r2 p7 e& _6 H( V9 |
  873. /*                Nothing                                                                                                                        *// c# q0 u5 _1 E3 X$ s% V+ n8 {
  874. /************************************************************************/
    3 S2 _( w" b3 h
  875. void Sector_Erase(unsigned long Dst)4 g/ S! I; K3 t" \
  876. {
    / s% j1 L6 ]* Y! \" Y" _

  877. & Z5 s1 u# e( P$ Q
  878. 8 e0 Y; O( Y" x4 H
  879.         CE_Low();                                        /* enable device */
    ' Q- [+ ~/ m! P
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    * e7 y' B2 y* j  n1 P  U% g
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */& y0 o( Y/ a0 V5 E
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));8 j. |0 j; ~$ |# P) m
  883.         Send_Byte(Dst & 0xFF);
    " A% `, P( i4 e
  884.         CE_High();                                        /* disable device */
    ( A/ ]/ e8 L9 i; b* h( ^
  885. }       
    " ?& F, c/ |4 w3 B* [. j
  886. 4 Y" [; \4 f2 }" `( K0 c8 c
  887. /************************************************************************/! o9 A; V) ~: v
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    ! o: G4 S& r' O# E2 B# S7 t" X
  889. /*                                                                                                                                                */& G7 h" g( E: @9 d/ u5 o
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */! R+ f6 c& I/ V7 Z' S0 Y( a5 R5 k
  891. /*                                                                                                                                                */
    3 b  v( |0 W2 |, v
  892. /* Input:                                                                                                                                */1 m9 z9 X$ m$ @  l- u$ }
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    7 E" K2 ]5 A1 y$ o/ Y
  894. /*                                                                                                                                                */5 Z' D& k; q, f% b9 Q
  895. /* Returns:                                                                                                                                */
    , z: [9 k3 m8 h- _8 e+ c8 z
  896. /*                Nothing                                                                                                                        */' p& g3 U2 \2 |, q& t6 z+ b8 S
  897. /************************************************************************/
    * o* U, Q- ^( ~, W
  898. void Block_Erase_32K(unsigned long Dst)
    " S) o. H- H/ T; C
  899. {
    9 p. n8 a. R4 ?: W$ r: l
  900.         CE_Low();                                        /* enable device */
    . k& }: _( t7 s8 C2 P# h6 Q1 n
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    / s/ A( I4 J+ `: B" [  P! l# z, D
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    1 _. b; \' I! S, r2 p
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));% @) l' p8 L: p9 K- e/ p
  904.         Send_Byte(Dst & 0xFF);  O8 `" h4 c/ E* w! Y
  905.         CE_High();                                        /* disable device */: g  \- z# k( B* j: Y; \! _+ H
  906. }
    5 t- E: x+ L* X( z- C- {

  907. + J! V3 ~$ i5 p6 u% I
  908. /************************************************************************/2 T3 N& r# X" V4 r2 H" L
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    9 b: _& _3 a4 r5 W1 ^# z5 P
  910. /*                                                                                                                                                */
    * o% k4 @. m) h0 ~6 J
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */5 l" n: s3 e7 b0 O% V. g$ X' l/ r
  912. /*                                                                                                                                                */
    # n' V& [& K( |5 r2 X: S7 a6 P
  913. /* Input:                                                                                                                                */
    8 z, {$ z. P2 s# Y$ x
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */+ f+ h# g. O6 ?) b3 T; o
  915. /*                                                                                                                                                */
    " k2 E: }2 r0 D' v' w9 J$ [5 V, {
  916. /* Returns:                                                                                                                                */& P3 K. {2 k" c, |2 e, B
  917. /*                Nothing                                                                                                                        */
    % y& `% S4 M+ ~9 `  D3 J
  918. /************************************************************************/. P. D+ r1 a4 E% n: r/ O3 s# p
  919. void Block_Erase_64K(unsigned long Dst). r/ c( _" L; D4 P; E4 c* p
  920. {" _7 z" g. Q4 R' J# ~7 p6 n
  921.         CE_Low();                                        /* enable device */& T) s1 o7 K, }
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    " U( e) H) D9 _/ N4 A
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */* d, i, f4 d" R# D' ?: R* m7 ^
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));7 r% r3 I3 u/ S  |! m  f8 p* V" v
  925.         Send_Byte(Dst & 0xFF);
    1 P& G9 ^' ]  a$ Y- q3 a% n
  926.         CE_High();                                        /* disable device */# G& t2 P" G5 D0 ^7 S* |# S
  927. }( q2 J" Z7 D. {8 R! d# s

  928. * Q$ m; @1 y* k8 s, a
  929. /************************************************************************/) c1 N/ P$ r! E- o3 W% b6 G7 D
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    : I6 W# A/ {( h* d- K
  931. /*                                                                                                                                                */* l: W: `# P/ e. O- `* M% i
  932. /* This procedure waits until device is no longer busy (can be used by        */
    7 ^& F' ^' I  _  b$ z* q9 l
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    + V7 b& e3 C" C+ Z- @: j$ ~1 @
  934. /*                                                                                                                                                */4 K9 p/ c) f8 p* o9 e9 J
  935. /* Input:                                                                                                                                */
    " J- @, T. f- {; k- `- y
  936. /*                None                                                                                                                        */$ {4 ~& S, z( ?
  937. /*                                                                                                                                                */' b. b! p$ [+ l4 f5 A
  938. /* Returns:                                                                                                                                */. }7 T& y7 w# [/ s! ^9 X0 u2 R* F
  939. /*                Nothing                                                                                                                        */' d6 n) v* F( U* J) p
  940. /************************************************************************/1 I3 |2 ^; u: e. r& d
  941. void Wait_Busy()
    ; a+ G+ w( u9 G: K- R
  942. {! b3 b- e2 J0 G2 l, \1 h
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */3 U5 k; U2 t- E' ?
  944.                 Read_Status_Register();
    1 x  m$ X; z" \" k
  945. }
    ) }- F. K. B/ n) Z% I
  946. 3 M# c8 p/ R9 ?$ z6 @$ x) v! P/ M$ ]
  947. /************************************************************************/
    ( k' Q; c6 u% N  J2 }8 K+ t$ M
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    ' J0 n+ c) p4 `$ y; |
  949. /*                                                                                                                                                */
    + n7 |' M7 Y( g2 u
  950. /* This procedure waits until device is no longer busy for AAI mode.        */! E1 R$ J- W6 ]
  951. /*                                                                                                                                                */, G# I6 x7 h7 i$ w
  952. /* Input:                                                                                                                                */
    : l! }( Q$ o1 y
  953. /*                None                                                                                                                        */* `& A+ d, r2 W
  954. /*                                                                                                                                                *// ]4 n  D7 V0 {7 ]; n$ E
  955. /* Returns:                                                                                                                                */
    3 x0 [2 z7 N* |5 p) _8 t7 a* S
  956. /*                Nothing                                                                                                                        */
    , p$ L) T! v. P0 x' h6 x
  957. /************************************************************************/
    - X, [9 n) Z4 `+ f- X! K% f
  958. void Wait_Busy_AAI()( ], _3 B3 o" J$ e& a: s; V" n" a; F6 k
  959. {
      E) W* t5 u0 X; X8 U
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    - R- W' a, {. B5 k4 r
  961.                 Read_Status_Register();0 @; r8 F6 W/ R& P3 C. D
  962. }2 O: H# Q5 W6 g
  963. 0 N) F2 Y. Z/ P/ C7 Z
  964. /************************************************************************/
    ; U' D) ^/ A- j& H0 _
  965. /* PROCEDURE: WREN_Check                                                                                                */
      t" A0 @$ c0 M" n7 v
  966. /*                                                                                                                                                */& c1 f* o. |0 T1 [1 X5 E
  967. /* This procedure checks to see if WEL bit set before program/erase.        */* e. e' i6 {9 T1 l. V# s# y% w3 F
  968. /*                                                                                                                                                */% [, {% d' ?2 J6 m
  969. /* Input:                                                                                                                                */0 l/ n$ |5 P( g) ~5 |1 S! g
  970. /*                None                                                                                                                        */
    : A( @, }4 C4 }1 }2 ^0 _
  971. /*                                                                                                                                                */
    3 ~1 ^$ A7 H2 G( c
  972. /* Returns:                                                                                                                                */
    4 a& Y. p+ J- E, a: b
  973. /*                Nothing                                                                                                                        */3 a+ S# Y& A! T- ^. i' }
  974. /************************************************************************/
    ! ^5 C6 Q5 c0 m+ `% o* Q
  975. void WREN_Check()' O, W$ a7 D( c
  976. {
    ! z# u* B% ~. Y4 T, C+ _% B  x
  977.         unsigned char byte;
    * G% L& F$ {$ q& s
  978.         byte = Read_Status_Register();        /* read the status register */
    , O. K3 f7 ]7 ^% y( x3 }
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    $ g( h5 r) Z% J$ [1 y
  980.         {
    % P  ^6 l% R" [8 s2 [; ^# L( o. _% Z. U
  981.                 while(1)8 T* v; e4 N8 r
  982.                         /* add source code or statements for this file */- L5 i4 \( R, V* u" Q1 a1 l" f% B
  983.                         /* to compile                                  */& a- p. ?( M/ K0 N3 B2 a
  984.                         /* i.e. option: insert a display to view error on LED? */
    9 y& q* l# G% F. A% h
  985.                  
    . g0 K5 q6 b% a' ]
  986.         }
    ' E9 Q: D: c! d6 R
  987. }8 H: O4 Q1 C0 [5 X6 i
  988. ( s2 ^4 A1 w, ~/ z6 ]
  989. /************************************************************************/
    ( ^/ j( P: |: i
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */( ?. L' i" Q9 M1 \
  991. /*                                                                                                                                                */
    ( L; b  c& b/ @. K8 u: N
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    6 @5 z% P" O2 D! n! ]" ]
  993. /*                                                                                                                                                */2 j! d! A, O1 p+ i1 X; O& p
  994. /* Input:                                                                                                                                */
    ( c1 Z6 A) T, `1 _9 s4 ~  S& p7 p
  995. /*                None                                                                                                                        */
    ' m  P2 c2 l3 T! L* r- H( P( Y
  996. /*                                                                                                                                                */
    / ?$ k* D  ]7 m) m9 s6 P: b
  997. /* Returns:                                                                                                                                */- }, u* H0 S3 r9 S% l
  998. /*                Nothing                                                                                                                        */
    $ p% H- `2 ]0 X0 @( b' J% K7 B! G
  999. /************************************************************************/$ d2 E" a0 M' W: u5 b
  1000. void WREN_AAI_Check()
    ( _& a- j+ C" x: i
  1001. {; x2 |0 n$ W- `0 i8 J
  1002.         unsigned char byte;- O7 s" G0 S  A# O% h* c3 p
  1003.         byte = Read_Status_Register();        /* read the status register */
    - W1 ^  I, E2 ?- }/ _9 ]# b
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */" b- s, J$ i+ s5 m( V2 \8 H
  1005.         {& V. F4 B$ o+ Q- a, F6 F. m
  1006.                 while(1)               
    % n3 k/ S- i( b: ~8 B
  1007.                         /* add source code or statements for this file */% R6 ]/ \8 U6 L
  1008.                         /* to compile                                  */
    ) ?/ e. ?! p9 H0 x5 O; [/ c6 A
  1009.                         /* i.e. option: insert a display to view error on LED? */
    6 j" [! c& {  o3 k6 G
  1010. ) ^$ A, G! W# c, T
  1011.         }
    4 s9 }# ^5 z$ R% [9 G4 N$ ?8 T* S
  1012. }
    8 f- l) e. j' A# E' H( l8 r
  1013.   D! @* C% y) f
  1014. /************************************************************************/9 `2 }4 Q" B+ W% ^0 ^9 Y$ l
  1015. /* PROCEDURE: Verify                                                                                                        */$ i, {  ~4 ]; k  S+ _; L' E
  1016. /*                                                                                                                                                */
    ' T2 j3 m. g% R' i2 ]+ A$ p  R+ N
  1017. /* This procedure checks to see if the correct byte has be read.                */- X8 y) v6 U; h0 H+ S
  1018. /*                                                                                                                                                */
    & `1 H, J% m: z0 c+ J/ O% H- _
  1019. /* Input:                                                                                                                                */
    8 [% R: g: I8 g; u: w8 y5 h; ]2 e  K
  1020. /*                byte:                byte read                                                                                        */6 N/ f5 F# I; w$ t. T! H0 X
  1021. /*                cor_byte:        correct_byte that should be read                                        */4 f1 ?* [$ q8 O0 Q4 h3 K
  1022. /*                                                                                                                                                */% o. [6 e" f$ {: m% v
  1023. /* Returns:                                                                                                                                */* V" w1 E% t5 {8 f* l
  1024. /*                Nothing                                                                                                                        */
    * A+ b& O9 k) Q# E- o% y. E+ Z
  1025. /************************************************************************/
    1 H) `% y) I2 c3 M
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    # F) C, @  [: I
  1027. {* b- h( G! A& w! Y6 D$ p3 ]9 y
  1028.         if (byte != cor_byte)2 d4 Y" F8 n, G8 S
  1029.         {; Y$ G$ p4 ?) }* H0 g9 i
  1030.                 while(1). @, G2 c% |9 s" O6 k) H
  1031.                         /* add source code or statement for this file */
    & B: W. A5 _- c7 w
  1032.                         /* to compile                                  */# E% R, Z( |+ B! @# y( u; j2 \% X
  1033.                         /* i.e. option: insert a display to view error on LED? */
    2 ]! F: g4 ~. c1 Q2 H0 e) J
  1034.                
    1 l+ v, H0 D& H3 ]% ?1 I! N
  1035.         }
    * x: ~% Z8 D/ W
  1036. }$ I4 A/ F! j" U8 z6 R  @
  1037. 1 _7 x. w: }: p

  1038. $ v0 ^4 I% S2 A9 z7 b9 d! X
  1039. int main()& q8 k$ e6 P+ T. H) f
  1040. {. L; X3 T' k5 ~) L) K

  1041. # U. E* _! j) f2 N- |8 S# O& t
  1042. return 0;
    ; ^; s, ]7 g( W
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:/ ?% q4 ~0 ?7 |* j% X, c, j
   main()
( \* t  J" ?% S1 d& U  H   里面怎么是空的呢?
: l& s4 o% g, V8 ~$ a. U   发一份给我吧, f  {. D# F1 @8 z1 U
mail:luyijun2005@hotmail.com. i# H4 d2 a" M6 K" P# `" A, d
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
/ n% [+ ~3 q: g1 r( x9 ~2 e. k2 Z1 M. s0 Q$ e0 x
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
2 `8 A" G9 k. {1 m6 G; GEC的代码在哪跑,你看DS的说明,每个EC都不同的。
7 k1 t8 H! [- B! l- dOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?9 f6 m0 E" d# H; ]& c
上面几个问题是你没看任何东西而白问。
6 y& G# m5 s! [0 G, c" F2 f- @6 b
; a" L- P7 w( Q+ C至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。) U6 c  a  L0 y' ]+ `* ~
8 b0 R9 d* a( w# w$ _
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!9 _% l: ?( v% V) C' p  j; R

$ U  v+ y& @% T, m1 J5 }关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”$ r" U' J+ C# s& W

6 h5 Q0 T( O' c! z关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...5 N, {6 X0 [- j( V1 \2 p) H/ Z

% r) g, ?" g1 G, d0 j不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
$ L- A# f) d8 B) D似乎要把SPI能support 到最大,这EC chip应该有好卖点9 I7 x. `$ O: `
BIOS功能要不要强大,也就决定了SPI Flach的大小
& Q* f) x; y* |) t8 N我是这么想的~让OEM去决定要挂多大!
# P; l$ F  |! }1 n4 {: ^如果我司有BIOS工程师就好了~哈7 t  G3 ]; m% o; B
WPCE775应该算很新的东西,来看它支持到多大?  m  }8 y/ s6 S5 j: K

" x. G+ z& ~, t. C另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
2 R6 N, M* b' e+ _其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.& X/ n& w" X! Q( @. ?6 p

7 h. d, W5 B  r9 y! k' C1 k7 p这份driver收下~希望以后有用到
" [2 P# X+ T: {- `0 D5 `9 ?& s  d4 t谢谢bini大大& L+ ^4 X5 d/ B" ~# k
  c# Z4 B, O3 X1 k; @3 X1 Y  \
很新很新的新手,如有错误请指正 (准备看第二家的EC SPEC)
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

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

这个函数看不懂Poll_SO()

void Poll_SO()6 ]" O' D. U5 k
{% {' U& F7 m: P" \* ~8 v7 o+ K. n2 V) O
        unsigned char temp = 0;
' z( B7 _; g0 \+ \        CE_Low();4 n' r# y7 B# ]1 g
    while (temp == 0x00)        /* waste time until not busy */
$ O7 \* k6 l( f6 c8 W                temp = SO;$ \5 @2 n# Z* {5 p1 D! e1 x
        CE_High();' [' f3 ]0 Q3 s6 E
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
5 c3 Y/ d  n3 {+ P( _2 f{
  k/ ~7 l8 S; X+ K) D        
" P: E$ x2 w3 \' m8 ]        unsigned char i = 0;4 W* v0 {, N% _. P5 d( s+ H
        for (i = 0; i < 8; i++)0 [0 u* f* ]0 I  `7 r$ u6 z+ S- ?# y
        {
0 M; N+ v) P6 P3 O! Q0 ^                7 _; E! K% E6 E
                if ((out & 0x80) == 0x80)        /* check if MSB is high */
, c/ c1 ^6 O5 f                        SI = 1;1 W- w7 N; Q5 W4 b5 A7 z! B
                else
7 U& }  K$ R2 T- p                        SI = 0;                                /* if not, set to low */
3 b6 F. W* k) Y% p/ J+ z: b6 O 问              SCK = 1;                                /* toggle clock high */- X; h' T- w' x) [
   题            out = (out << 1);                /* shift 1 place for next bit */
! N! f1 c& G& @% M) |: _                SCK = 0;                                /* toggle clock low */  Z% J. ~# `2 g0 C$ ?7 b9 T7 j4 v
        }" v  [  S! U- ?6 C1 U4 `4 ~  I! n
}
+ G3 C0 F% \) T7 d1 d; z 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-12-1 06:43 , Processed in 0.083832 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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