找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55251|回复: 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! Y/ l; K9 _; f- L8 ]
  2. 6 L9 c2 X3 f8 b5 X
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory; C. `" I' o! c0 ~/ _

  4. # ~2 Q& u4 Y7 e% l; D" C  @
  5. November 4th, 2005, Rev. 1.0; l# x+ m3 p2 e- N* N& V

  6. 0 X7 Q1 V2 {, m: r
  7. ABOUT THE SOFTWARE& e; @  P' t, C1 m5 P; s$ J# A
  8. This application note provides software driver examples for SST25VF080B,0 h8 A; n( n; A" B  i7 G
  9. Serial Flash. Extensive comments are included in each routine to describe 5 o: B5 D' a* }$ _/ B
  10. the function of each routine.  The interface coding uses polling method ! R; u1 i4 D/ {# H; e# J$ y
  11. rather than the SPI protocol to interface with these serial devices.  The! G9 v  G9 H/ f) c
  12. functions are differentiated below in terms of the communication protocols
    9 e9 W  a4 G6 E- h; A0 ~
  13. (uses Mode 0) and specific device operation instructions. This code has been
    - f. V. f5 H( h, l1 [6 z
  14. designed to compile using the Keil compiler.5 s- n) f$ ~8 ?4 D! M
  15. : R/ a2 k6 f. T' Y3 K0 v6 M
  16. & R% l5 d; D$ z; K8 X4 i0 w
  17. ABOUT THE SST25VF080B
    - e: V0 S: U+ t, ]

  18.   Q9 ?9 A- Q6 J0 n/ b! g" {
  19. Companion product datasheets for the SST25VF080B should be reviewed in 3 s- B5 f0 r; r2 C3 j& z
  20. conjunction with this application note for a complete understanding   R% m( L, S5 i" b
  21. of the device.
    ' D4 s: Z( F* v4 j4 L) ]" b
  22. & _$ F, N; u2 N) ?: i7 S( e; ^3 ~

  23. 4 a+ c$ X% U$ d5 q: n8 I' l
  24. Device Communication Protocol(pinout related) functions:
    7 U* d! Q3 i( W. {. k
  25. 8 w, w; e9 J5 W& M
  26. Functions                                    Function( ^. B3 O1 x  m; X7 l" ]
  27. ------------------------------------------------------------------
    % f( T5 ]$ G1 P  K
  28. init                                        Initializes clock to set up mode 0.
    ' f! T9 j1 |$ l. x, n
  29. Send_Byte                                Sends one byte using SI pin to send and ( B+ N& n" c0 g5 ~8 n5 G* s  K; [
  30.                                                 shift out 1-bit per clock rising edge
    8 s. g' W& ~/ Z
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    + s2 V. q- V: Y4 L- ^+ T; K
  32.                                                 in 1-bit per clock falling edge0 r1 \8 o$ ~; |1 X. Y% [
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    * A  B7 y7 ]# K& }
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high/ D# b8 i3 s% m* a
  35. CE_Low                                        Clears Chip Enable of the serial flash to low8 C$ K5 Y. `0 Q. z  y3 [( W) M
  36. Hold_Low                                Clears Hold pin to make serial flash hold6 k( a: J( K) w, E
  37. Unhold                                        Unholds the serial flash
    1 j6 `) U1 w9 x0 U0 h  l
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    # ]. ^& [$ j/ G% q) S" Y7 }
  39. UnWP                                        Disables write protection pin; [' _. o; ]8 ~
  40. # r  `& D: S7 X/ O
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code& p; s, c1 h; [1 u$ p  ^
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your, d& l; |% D7 f
  43. software which should reflect your hardware interfaced.          / b; B7 r7 }% Q9 Q% Z: [

  44. , y/ x" m6 q! t4 H

  45. 5 s/ l0 f3 }" f* y
  46. Device Operation Instruction functions:
    3 l6 n& H% |2 F9 d! x3 T  [7 E2 w5 I# b
  47. 5 N( T1 g! j$ C8 i/ w
  48. Functions                                    Function
    ! M2 m5 R7 F/ z& f; s$ j: d
  49. ------------------------------------------------------------------
    5 m9 `. ]" H( k: P$ G% D& F' g9 V
  50. Read_Status_Register        Reads the status register of the serial flash; {7 V0 y  N% @* Y( U/ t
  51. EWSR                                        Enables the Write Status Register+ i! b" X1 |, [& P3 K- [
  52. WRSR                                        Performs a write to the status register% a( w; b9 w: D6 G; g
  53. WREN                                        Write enables the serial flash
    7 m" w1 o. e- w/ Z( y2 C8 M% C6 ~
  54. WRDI                                        Write disables the serial flash
    9 b) Y2 [+ B$ J9 {6 t. F1 ]. w
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming6 ~7 o6 j( l4 g
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming% j; e& q6 s* |/ f2 Y! `9 P5 D
  57. Read_ID                                        Reads the manufacturer ID and device ID- v7 w. ?& K: @6 v' D/ b* A
  58. Jedec_ID_Read                        Reads the Jedec ID
    . m% q, v8 |6 I/ n; `
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    7 Z6 F6 @) e; q4 J
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    0 |/ K  b  V# u  H% X
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)4 D3 @" ]( d! h# g; x% _9 ?
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    ) P! {! M  }; c5 \, H& f
  63. Byte_Program                        Program one byte to the serial flash
    8 Q* g, }, a* Y* m$ w; A1 y! L, d+ j
  64. Auto_Add_IncA                        Initial Auto Address Increment process4 \' G% w" k6 V/ |( _$ t
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    4 B* a# {. D+ m
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY+ O& r; ?3 v$ D4 C1 w0 L7 b
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY8 L! o( V; h" l1 {/ \2 P
  68. Chip_Erase                                Erases entire serial flash
    # ~* M$ x% e! s( e& {
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    - g# H& w$ G6 e% {3 W
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash+ |, S& i& Z* E2 }8 O% i; s8 }' j8 k
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    5 f' d6 L+ P; s8 h9 J" @( W
  72. Wait_Busy                                Polls status register until busy bit is low0 {; s0 g' j" |; _' Y
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    0 {: m& q* V3 Q$ M
  74. WREN_Check                                Checks to see if WEL is set
    1 t0 {7 p! Z% @3 \
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    / u6 X0 {" i: e, `; n
  76. : I* m( e' r0 h+ n8 p* p

  77. ' f, g' y; u% M  O5 v: n& e

  78. 7 Y- G7 p) q& M) U( K" J
  79.                                                                      
    - `0 t" L: H4 Y4 n7 R! D3 c3 W
  80. "C" LANGUAGE DRIVERS . q- u% W2 v# X2 O( x* S1 y( A
  81. 5 I3 r5 \3 W, r
  82. /********************************************************************/& I$ ?: d7 ]* u" B9 `6 P
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */" ~6 v% [/ T2 g3 D; p; D: }2 G/ v4 A! }
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    5 Z  w  ?( \( q4 ^! x' M2 ^
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */. p: T' W2 z6 |2 f) R, a
  86. /*                                                                  */
    : x( A; @' S( I; X% y/ w: J
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    ; P0 g7 x; j: _$ [0 j6 G: ^
  88. /*                                                                  */9 O) H! D( j6 s
  89. /*                                                                                                                                        */) c0 L. v# w; w1 m$ Y
  90. /********************************************************************/
    2 v: e6 N( K& x5 `2 X: |, x) b7 S5 k

  91. , z8 z- l" H: I! k# ^) b$ D1 D
  92. #include <stdio.h>
    , Q6 \  q+ d- }, y$ t- ]9 r
  93. #include <stdlib.h>9 q0 V/ a+ t4 i7 x

  94. 1 V% m( O* E3 ]5 R! e0 _
  95. /* Function Prototypes */
    8 @1 w+ V3 Z. x. G- Q3 I5 M5 M

  96. + V1 q- D: {& K
  97. void init();% V$ f* {  n  w( q
  98. void Send_Byte(unsigned char out);
    / \/ u4 i8 d' W: `+ Z# x
  99. unsigned char Get_Byte();5 u6 e  i1 \% [) B& }( ]0 Q+ c
  100. void Poll_SO();
    $ T) F% w9 p* Z) p+ R/ `
  101. void CE_High();1 P2 i6 n  S0 d; [
  102. void CE_Low();
      ?  f) ?$ W# Q2 A& J; I' I
  103. void Hold_Low();
    8 v+ m. }3 f' E. s! i8 C
  104. void Unhold();0 K" b; ~- t5 ]- P3 o& Z1 y
  105. void WP_Low();
    0 C4 w0 b7 z8 {
  106. void UnWP();
    8 v9 |8 S  E  G# V$ |
  107. unsigned char Read_Status_Register();; i3 @/ X# Q. f8 H7 \
  108. void EWSR();
    / O* w% _/ j( w1 A1 `
  109. void WRSR(byte);
    + ^% b; p3 r% p# B; f! E2 G  u4 z1 c
  110. void WREN();. J7 _! m) F: E/ D) U8 C. K
  111. void WRDI();
    0 a9 R. r; r2 O9 W5 t
  112. void EBSY();/ E, o7 V! S/ e$ z
  113. void DBSY();9 t6 {$ ?( X7 z: H) ~+ G1 @3 {
  114. unsigned char Read_ID(ID_addr);/ o1 z' ^4 X" l5 N
  115. unsigned long Jedec_ID_Read();
    - N; G1 o; X0 c& U' z' p1 Y
  116. unsigned char Read(unsigned long Dst);' D: ]! y( U' F# z
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    : i& o7 E. w/ X/ t
  118. unsigned char HighSpeed_Read(unsigned long Dst); : \. U2 V  }2 B
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);" e) o# O0 J+ w' k& H$ ]" x7 m& R
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    + q  ]1 k1 ]* l$ o5 F* k4 u, V. ^7 k
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);( L; t& Y. c) s7 }; X
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    4 H, a" t0 ~1 p/ U. k3 l
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    6 h' |: t- F* n9 c2 h) Y
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);; q% L; @( G' _5 ~" A. v
  125. void Chip_Erase();
    $ ]2 {( B& `4 R3 T2 V. H) t
  126. void Sector_Erase(unsigned long Dst);. R6 ~& j" _( i
  127. void Block_Erase_32K(unsigned long Dst);& e' D1 k) d* T' ]2 c/ c
  128. void Block_Erase_64K(unsigned long Dst);
    : |, K- b2 g; }' [! |
  129. void Wait_Busy();7 E) F7 |: [' j6 N" I
  130. void Wait_Busy_AAI();! M* H3 i* g3 ~- M3 C
  131. void WREN_Check();
    1 n9 h* R3 U: K
  132. void WREN_AAI_Check();5 Y( V3 S. H* ?9 q/ s2 ]; C
  133. ; {4 Q: z2 ~! p/ F  v4 g
  134. void Verify(unsigned char byte, unsigned char cor_byte);$ [5 s9 k0 [2 D) d) P

  135. : o) h# B; ~# c- i% y7 N6 D
  136. unsigned char idata upper_128[128];                /* global array to store read data */" T* E4 _9 _; U& ~1 i: C1 [% n
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    4 }- j% K$ g- \1 ~( s/ H
  138. 3 T5 [& }. w0 ]: e9 x% d6 E# I& c
  139. /************************************************************************/' r8 p. j  D2 ~1 A9 ^# l) f
  140. /* PROCEDURE: init                                                                                                                */: ~! r4 c5 w) i& w, S2 S" H
  141. /*                                                                                                                                                */
    ( ^! J' k6 D! V# q
  142. /* This procedure initializes the SCK to low. Must be called prior to         */% g/ |& m$ p6 z5 |) x5 O# u
  143. /* setting up mode 0.                                                                                                        */; h; I, P, B( _0 d5 B/ k/ O
  144. /*                                                                                                                                                */
    / x7 j; y8 Z- M
  145. /* Input:                                                                                                                                */
    , @5 U" Y% C& S' V
  146. /*                None                                                                                                                        */
    4 Z9 f8 A& P  M4 \( g+ m2 w
  147. /*                                                                                                                                                */) ?4 Q0 ?- ^: p$ ?( `
  148. /* Output:                                                                                                                                */8 U9 i# K; r5 l7 I
  149. /*                SCK                                                                                                                                */5 f, e, F2 C7 u5 Y' t7 a
  150. /************************************************************************/3 _" Q1 v# x6 e/ H
  151. void init()
    ' J: z& k0 I# {
  152. {
    0 i/ S3 i" L" ^& _- D
  153.         SCK = 0;        /* set clock to low initial state */- \/ `* \9 h8 ^  `* e2 ~
  154. }' @: l" Y/ @6 G
  155. # d/ d  g6 S/ ~) G% K: \( v, `4 x
  156. /************************************************************************/2 W: e( u" ^; C2 g7 R; h
  157. /* PROCEDURE: Send_Byte                                                                                                        */9 N7 |0 t' d) _2 c
  158. /*                                                                                                                                                */3 P" w4 ~$ k0 {5 H) a1 x! P# I
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */" X; a1 q: g, W* p6 n: b9 o( A
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    & D$ D0 F. d) x9 \) ?6 `. S
  161. /*                                                                                                                                                */$ B) }* A0 t0 o/ b. p- A
  162. /* Input:                                                                                                                                */; i, L/ l" Q. u8 E
  163. /*                out                                                                                                                                */
    + A1 }5 B9 D  m  }- c1 t3 `
  164. /*                                                                                                                                                */
    * s: @- d" \# i% B2 M
  165. /* Output:                                                                                                                                */( ]4 I" v* ~4 \* _7 \
  166. /*                SI                                                                                                                                */3 G! J0 q6 k* X( p7 M
  167. /************************************************************************/: a/ ~) g, k! K8 t. d. k
  168. void Send_Byte(unsigned char out)# M/ }% H, C' y- V! g. `- R
  169. {- D0 V% [& k$ K
  170.         : K5 B5 |  k5 O$ b0 F
  171.         unsigned char i = 0;5 H7 J% Z: ~0 w1 e1 M
  172.         for (i = 0; i < 8; i++)6 ?: B) f8 M2 ?
  173.         {( E3 G: O7 _' A4 \* ^4 @: L
  174.                 4 }$ B. t8 A2 W; ?9 c
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */) C3 Z5 }+ u4 a  H
  176.                         SI = 1;- ~6 k6 A9 A6 Y3 U. z: j
  177.                 else- l) h+ ~% o+ S
  178.                         SI = 0;                                /* if not, set to low */
    # }: ~- R  A9 E1 o/ [7 [
  179.                 SCK = 1;                                /* toggle clock high */
    0 C: F7 o* Q; ~/ }
  180.                 out = (out << 1);                /* shift 1 place for next bit */* ?1 |! y% o+ h: j
  181.                 SCK = 0;                                /* toggle clock low */
    - ]5 M0 h8 O$ a5 O- f
  182.         }" i" z/ F: K" p' V$ q1 }
  183. }
    5 p; i9 l" {+ x7 Y

  184. ( ~9 l9 s, B0 q. N( c
  185. /************************************************************************/
    % L$ A" h& G7 y( P  l8 Z7 W4 X1 i
  186. /* PROCEDURE: Get_Byte                                                                                                        */9 T  `: a# A$ J% J! L- Z* A
  187. /*                                                                                                                                                */- E1 W9 f! @  B) C: g) c" W" Z+ A
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */) S3 l- A! i' `  \. ^
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    & u# z/ J: |! w+ q
  190. /*                                                                                                                                                */+ y6 ~* T: Z  c; u8 @
  191. /* Input:                                                                                                                                */+ C. H2 K2 I+ U/ i
  192. /*                SO                                                                                                                                */
    # k- B! O2 W  L
  193. /*                                                                                                                                                *// l1 U" T7 n8 m" x% f. o9 `
  194. /* Output:                                                                                                                                */
    + j6 j" e- J0 s! v/ u6 _: c& T' J- N
  195. /*                None                                                                                                                        */
    * L1 h4 g6 d8 z9 J- r3 \
  196. /************************************************************************/
    ! s4 _3 H' t2 u  G# ?9 b; C
  197. unsigned char Get_Byte()0 Z/ s+ f1 q5 h
  198. {
    5 L: B2 X3 ]0 c5 E
  199.         unsigned char i = 0, in = 0, temp = 0;
    ( n8 A* B7 [) F. X. W2 x' ?; {
  200.         for (i = 0; i < 8; i++)$ C! w$ S) U- Q! ^/ x
  201.         {- o% y5 G' {$ }" z9 F
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */' G8 [& d6 D" a' q3 Q4 c
  203.                 temp = SO;                        /* save input */
    % u# C, V( L, r4 u' \
  204.                 SCK = 1;                        /* toggle clock high */
      u( B  q& k3 w, j2 y- p- W
  205.                 if (temp == 1)                        /* check to see if bit is high */, v& ~5 N2 F1 b: Q9 D
  206.                         in = in | 0x01;                /* if high, make bit high */) q  s' A3 E; v

  207. 2 C% ?( O  A: ?( Z1 J8 a( ^9 k6 r
  208.                 SCK = 0;                        /* toggle clock low */2 H0 U" h& Y( y' A. F1 n) O% g* Q9 i, [
  209. # U1 |4 e% [2 p7 v" t1 Y% g
  210.         }/ G: [* H% K( \( |  L+ F$ B
  211.         return in;
    ' E# B2 B% J6 ?1 t7 \- g4 u& [8 w" ]
  212. }" r4 l  a# p4 L4 ]) q/ \; \- C( @
  213. 0 L% i/ l. N) {9 X9 ^( C7 M- W
  214. /************************************************************************/
    * o$ h; y# D# r' p& M$ h5 B
  215. /* PROCEDURE: Poll_SO                                                                                                        */
    / m/ H/ L6 j+ m/ c$ R. z; P
  216. /*                                                                                                                                                */2 A3 r$ H7 f) B
  217. /* This procedure polls for the SO line during AAI programming                  *// j+ d, o# g5 x5 [! U
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/8 L! N' I1 x" X+ _' g
  219. /* is completed                                                                                                                        */+ h' Y4 T5 t( q* p) m1 n
  220. /*                                                                                                                                                */
    ! Q' e& R6 F' e% y9 _& Q: b
  221. /* Input:                                                                                                                                */# c0 N% A9 m# m
  222. /*                SO                                                                                                                                */; H, s5 K6 |5 U. s6 P
  223. /*                                                                                                                                                */
    ) A% X- A! k+ P4 I& m8 H6 V
  224. /* Output:                                                                                                                                */0 n+ ~% K/ E( q: [' K/ s" d
  225. /*                None                                                                                                                        */; b4 I2 w  I2 p/ |7 s4 x/ L
  226. /************************************************************************/
    + a( b8 ~; P$ [
  227. void Poll_SO()2 s4 {% M1 d3 M  j7 m
  228. {% M( c/ ?9 c" f8 F, P
  229.         unsigned char temp = 0;2 E% o, Y3 v# m( U8 E
  230.         CE_Low();9 E: V3 @$ N3 T7 C9 L$ ]% T
  231.     while (temp == 0x00)        /* waste time until not busy */
    : X: U- e% N2 q) F
  232.                 temp = SO;& b& q6 u. ~) k5 r+ a
  233.         CE_High();+ v* ~# p2 R" d6 }
  234. }7 R7 m9 _8 p$ o" h* E4 L5 Q* ~. M

  235. 5 M+ A/ |! N2 B- v0 e( c1 `: o
  236. /************************************************************************/" z) C; t' w! m9 t
  237. /* PROCEDURE: CE_High                                                                                                        */+ T0 h' w; `, {; G
  238. /*                                                                                                                                                */0 w7 f  d5 D% U" Z2 ~! u" q
  239. /* This procedure set CE = High.                                                                                */& b9 K, t* N- C1 c2 k3 `2 {
  240. /*                                                                                                                                                */0 v7 f4 h4 N8 W' [1 k, G( i' H
  241. /* Input:                                                                                                                                */# d+ I! ]; Z1 |4 I+ V1 ^3 T
  242. /*                None                                                                                                                        */
    & i0 h* Y  F9 ^1 Z& A
  243. /*                                                                                                                                                */7 E+ z7 ?! `( W1 ]2 K
  244. /* Output:                                                                                                                                */
    ; S* V) r$ {. f" O9 M
  245. /*                CE                                                                                                                                */3 e) _% t9 H* ?; ~- e" D
  246. /*                                                                                                                                                */
    7 {" j; k2 i( t' E: L& ?; m# A, u8 R
  247. /************************************************************************/. @. R* N7 l1 R9 ^) y) m8 t. \. E
  248. void CE_High() . s1 f0 d) @, p0 ~5 {
  249. {
    ; k# A$ K" C. l. D! F- i/ U( }7 L& l
  250.         CE = 1;                                /* set CE high */) G- b  |; ~5 d  ~" x+ m" z9 ^
  251. }
    ) E. b% c' U. w* k

  252.   N; `+ f2 t* D2 A/ X' i
  253. /************************************************************************/
    - I& L% {+ e! B- R' u% c
  254. /* PROCEDURE: CE_Low                                                                                                        */
    . n- o! y4 Q) o, V5 V
  255. /*                                                                                                                                                */
    0 w) v9 o9 G% q, G
  256. /* This procedure drives the CE of the device to low.                                          */( W" y# w. C/ q5 D- h- g' f* p
  257. /*                                                                                                                                                */
    1 j" q' c. f, p) c$ p. j
  258. /* Input:                                                                                                                                */! Z5 N' ~# n9 F: t2 |( A1 B
  259. /*                None                                                                                                                        */1 ?# Y) `% P  y1 P
  260. /*                                                                                                                                                */# @, V/ J0 `. |3 N) x4 I
  261. /* Output:                                                                                                                                */
    ! Z- X9 _+ f  ]# O  p' j7 |
  262. /*                CE                                                                                                                                */0 {: e5 P7 h( h. V7 L
  263. /*                                                                                                                                                */
    # P7 H7 W0 E* H; P, l: Q9 T3 I% R& h
  264. /************************************************************************/
    ' u1 R+ Z6 P7 l. V  ?5 V
  265. void CE_Low()
    - w" A( v" m7 B
  266. {        * ?! Q/ M( D3 x& K2 z/ v2 I
  267.         CE = 0;                                /* clear CE low */$ s( W: |" i2 p  ^, }
  268. }
    & i3 q, J0 \$ w1 E8 M

  269. 1 k7 \( v2 r3 A# D% L# U6 l0 Z4 a
  270. /************************************************************************/
    2 V# ^% w" E# E9 P/ q, X/ o2 C
  271. /* PROCEDURE: Hold()                                                                                                        */! w3 O; x; R; q7 |; @
  272. /*                                                                                                                                                *// y3 N9 a! C/ k1 K+ K
  273. /* This procedure clears the Hold pin to low.                                                        */
    ' S$ K' I. D' C" l- l
  274. /*                                                                                                                                                */* g: t1 Z- Z3 H) x- i
  275. /* Input:                                                                                                                                */( J0 m0 n; s5 q& D+ V# q/ l
  276. /*                None                                                                                                                        */; f" g! |6 K% [& _5 F
  277. /*                                                                                                                                                */
    7 x$ \; f' z* x; G
  278. /* Output:                                                                                                                                */8 d. x0 V, N" G& |' t+ y
  279. /*                Hold                                                                                                                        */
    # K, w% j! \. L2 L" ~$ Z) I
  280. /************************************************************************/- |. i* i, j- q: ^) d
  281. void Hold_Low()
    & g3 P9 L, C$ H  Q7 {& X$ b* z& R
  282. {
    - i: \  B0 L  I
  283.         Hold = 0;                        /* clear Hold pin */
    " B0 E  E$ e) M0 {+ V
  284. }* h9 ]- k  B  b% |- }! Q
  285. 1 C1 r7 y% c& c4 m( \5 S% d0 d
  286. /************************************************************************/( d( Q  A  j- _6 o  [* `: D
  287. /* PROCEDURE: Unhold()                                                                                                        */
    , d3 Q( k! A- A; g4 D! A  ~8 c, A- m
  288. /*                                                                                                                                                */
    - b1 G. M1 y& L& K: r% y; W; r
  289. /* This procedure sets the Hold pin to high.                                                        */# B. ?* m  ], O0 U7 O2 f  y
  290. /*                                                                                                                                                */
    5 R5 Z! k4 K6 U4 n$ X( M
  291. /* Input:                                                                                                                                */
    ( j: T4 l4 `$ ~
  292. /*                None                                                                                                                        */) ?5 K. w  L: \/ e" j9 K
  293. /*                                                                                                                                                */
    * K4 ^4 ~! ~- L! q6 c9 E
  294. /* Output:                                                                                                                                */
    * X1 O/ u/ _# ~7 S9 O
  295. /*                Hold                                                                                                                        */' B3 y: ?0 k$ m# k) r, d$ Z( S
  296. /************************************************************************/
    / x: ]. m+ a5 X
  297. void Unhold()
    / i' x# H7 M4 l% h0 q; W8 R7 H
  298. {
    * }  d# ~0 q/ A8 }+ t' m
  299.         Hold = 1;                        /* set Hold pin */
    . i% C5 E8 L$ \$ [, s
  300. }
    5 v* H% P: F, J

  301. ! C& c9 H; ]; m* N
  302. /************************************************************************/8 k5 _2 o+ l# [# Z4 c
  303. /* PROCEDURE: WP()                                                                                                                */" l( b/ {6 J, O; S; h3 l
  304. /*                                                                                                                                                */
    $ @8 j, g6 u7 d! L
  305. /* This procedure clears the WP pin to low.                                                                */
    : r( E! C- w+ m. X* G- ]2 B& [. ^
  306. /*                                                                                                                                                */
    ! h5 |" q& G9 G7 v
  307. /* Input:                                                                                                                                */& Z* E* s9 B0 |
  308. /*                None                                                                                                                        */
    7 \0 Q! z: G& r) E; ?, p
  309. /*                                                                                                                                                */; R# Z" x! r0 l( s, Q
  310. /* Output:                                                                                                                                */
    , `+ e$ c5 |' R. u9 D
  311. /*                WP                                                                                                                                */
    1 y. a( ~3 z+ a3 C! w
  312. /************************************************************************/$ c- y9 N2 n: y& c- d
  313. void WP_Low()
      ?- a9 B1 f! ?/ |& I5 z8 q7 ]3 j
  314. {# v1 W1 {$ {: a) r
  315.         WP = 0;                                /* clear WP pin */. C" P/ z. d" c5 j4 n' {2 b# f0 N6 B
  316. }
    ( ]) D) G& c% |- U
  317. 4 m1 ?5 X9 n+ b0 O! Z/ W5 U( B% d! m
  318. /************************************************************************/
    & f7 K) w2 r# Q% x* C
  319. /* PROCEDURE: UnWP()                                                                                                        */: ], k  p8 X& H
  320. /*                                                                                                                                                */9 D7 }6 c3 f& I4 \1 B8 j& B
  321. /* This procedure sets the WP pin to high.                                                                */  @: c3 B0 ~, Y7 }
  322. /*                                                                                                                                                */2 l- D5 a. n! C) ~7 [( y) R9 d2 q
  323. /* Input:                                                                                                                                */
    * m6 Z7 Y! e& F! o/ C
  324. /*                None                                                                                                                        */
    ; g- |# }0 B% J; K
  325. /*                                                                                                                                                */
    6 k6 e4 I# `3 v  y& j
  326. /* Output:                                                                                                                                */8 F0 O' N0 {4 W9 a6 o  @4 D& E$ @
  327. /*                WP                                                                                                                                */
    ! R/ \5 X. u) W3 `4 W' s9 }
  328. /************************************************************************/
    . G1 `/ |5 Q; }2 C
  329. void UnWP()
    ' A* Z6 d9 e: F( x% j
  330. {
    7 L1 U, X. a" _7 U# m9 c6 R
  331.         WP = 1;                                /* set WP pin */
    6 o- c- Y% ^9 d2 P
  332. }
    3 ~! b* [1 h% C. X4 Y; i

  333. $ p. b% O; B  q. _  Y0 `
  334. /************************************************************************/& G& w  h8 G& u% B5 P
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    8 Y1 Z% u% ^5 ^2 I5 r4 i
  336. /*                                                                                                                                                */
    % R4 n6 N6 t. K% l- _
  337. /* This procedure read the status register and returns the byte.                */' Y8 c8 ]* k8 Y" v" R  c+ {
  338. /*                                                                                                                                                */, D! A% F9 {7 m) z% x; Z
  339. /* Input:                                                                                                                                */2 I$ o" C1 x. T% f7 ]& B
  340. /*                None                                                                                                                        */; I! g, C( Y, k2 p0 U
  341. /*                                                                                                                                                */
    , J+ F9 f- g* g- @, U/ B
  342. /* Returns:                                                                                                                                */
    & `+ N- R0 r/ I* p& O
  343. /*                byte                                                                                                                        */
    % V1 I  ?0 F& D$ V3 d7 v2 E3 y
  344. /************************************************************************/
    6 D7 v! W9 w  m
  345. unsigned char Read_Status_Register()( v8 Z; k' n9 ^2 D. j8 Z# [
  346. {; i* m( a+ ?# f
  347.         unsigned char byte = 0;3 b3 f' j6 `  i0 x: g
  348.         CE_Low();                                /* enable device */
    ! C& I) c8 U4 |
  349.         Send_Byte(0x05);                /* send RDSR command */, }) M, F( t- \. p
  350.         byte = Get_Byte();                /* receive byte */& T* z* C% M5 Z  W, \3 v% }
  351.         CE_High();                                /* disable device */
    : O9 S7 R" T  U# c3 f
  352.         return byte;# |0 n; W( n4 p  Z  d0 P1 M
  353. }
    : ~% V  M: X4 h
  354. ( v3 Y4 }  c( n$ n
  355. /************************************************************************/
    8 m; M' @# i7 S. ~
  356. /* PROCEDURE: EWSR                                                                                                                */" _; K0 X0 G4 X$ Y5 c6 @! {
  357. /*                                                                                                                                                */- M( v+ G% h$ I8 R0 P* N
  358. /* This procedure Enables Write Status Register.                                                  */
    " Q5 f8 g  x) J( t; [  \& y
  359. /*                                                                                                                                                */
    , }$ c; x+ u+ R1 u8 |
  360. /* Input:                                                                                                                                */- R4 A: _9 o2 T
  361. /*                None                                                                                                                        */# [- O7 `+ D3 @' `. R+ T
  362. /*                                                                                                                                                */0 z+ [3 n- \4 m
  363. /* Returns:                                                                                                                                */
    " y/ \. |4 F0 i. n0 C4 c& I
  364. /*                Nothing                                                                                                                        */
    ( X2 U$ i( J8 J5 x0 ]9 I
  365. /************************************************************************/
    4 q3 q9 u% {! X
  366. void EWSR()' O- ~- q' S/ z& b* M& w+ B6 e
  367. {  j8 q6 y' n( L: E
  368.         CE_Low();                                /* enable device */
    3 X5 D, s2 H7 {# V+ Z4 d1 I; w' u
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    + ?' H* {" M; @4 B& ?$ w
  370.         CE_High();                                /* disable device */
    8 \9 E$ H( X: P8 a
  371. }
    3 T2 ~0 f; c. v# q7 y

  372. - O1 n* e6 }+ g0 X3 c
  373. /************************************************************************/- p; ~% @6 S0 |( z- T6 h6 S. z
  374. /* PROCEDURE: WRSR                                                                                                                */
    5 S2 a0 {2 c% r4 y9 T- f7 [
  375. /*                                                                                                                                                */
    2 Q2 H& {, A0 w, G; K
  376. /* This procedure writes a byte to the Status Register.                                        */& I5 q$ X4 u5 `4 o9 ^
  377. /*                                                                                                                                                *// Y6 I  g7 |+ d. ?
  378. /* Input:                                                                                                                                */
    % F1 u/ @0 u+ U$ \: D2 F
  379. /*                byte                                                                                                                        */3 f: x! s0 R0 Z7 h& {# l9 E
  380. /*                                                                                                                                                */
    # A% A$ X- G4 k5 x# c; O6 b  G
  381. /* Returns:                                                                                                                                */
    ; j8 v1 a0 T4 Q* {
  382. /*                Nothing                                                                                                                        */, S8 L, \3 m1 t' }6 i9 T( h8 x" c
  383. /************************************************************************/  o5 y! @- E# f+ m  A
  384. void WRSR(byte)
    * V2 Z7 E! G1 c: E) X
  385. {
    4 |8 r* ^: p! E5 j5 o1 Q) q  Y: ~" S- }
  386.         CE_Low();                                /* enable device */: k3 L0 u: d. k$ E+ q0 R5 }
  387.         Send_Byte(0x01);                /* select write to status register */
    3 P, W: m# M" [( S' ^8 O' s
  388.         Send_Byte(byte);                /* data that will change the status of BPx 8 y4 g1 _% \1 E7 |3 L+ ~
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */) c4 U  ]0 h- t9 I7 q7 I
  390.         CE_High();                                /* disable the device */
    $ E" m/ w2 k7 y- l" |  @( P
  391. }
    0 q5 y! Y6 c8 K# p
  392. . w! k; i# D% Y& n( V4 X
  393. /************************************************************************/
      _! P% V8 M, v" q. j* J. _
  394. /* PROCEDURE: WREN                                                                                                                */
    3 H( K( j5 L: p
  395. /*                                                                                                                                                */$ ?9 i% ~, g! g. h# G- r, I
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */9 L  a: l  T8 g- y* \- A+ f
  397. /* to Enables Write Status Register.                                                                        */
    0 O2 t/ C2 T  {; m( c$ c1 P( j) }, X
  398. /*                                                                                                                                                */) A9 k+ q- ~! j) r% x9 D; C
  399. /* Input:                                                                                                                                */
    8 Q9 ?7 D3 H: f( ~$ h
  400. /*                None                                                                                                                        */5 k' T& L9 n6 x1 P' B' }
  401. /*                                                                                                                                                */
    $ O4 V. ^; \/ i
  402. /* Returns:                                                                                                                                */
    " X4 a) ]+ g/ r& B
  403. /*                Nothing                                                                                                                        */1 b5 T9 |9 A2 V( [0 G) G4 C
  404. /************************************************************************// q5 D' }/ U: R# g( s9 E2 o- B
  405. void WREN(): V% @1 f. J, m  e/ B! x
  406. {: o4 m" Q! i4 c, O# {. A0 Y
  407.         CE_Low();                                /* enable device */
    ) K! R$ i8 r; T' f& ~* X/ r
  408.         Send_Byte(0x06);                /* send WREN command */4 i3 }3 ^9 E! R
  409.         CE_High();                                /* disable device */: ?- R/ p7 i4 e5 g
  410. }
    * c! f4 B5 a% n% j7 R

  411. " G' N5 C" `: m4 W" O7 e9 }0 w
  412. /************************************************************************/
    % e" y1 M+ ~1 C) \7 c
  413. /* PROCEDURE: WRDI                                                                                                                */
    ) E" q& O( ?, r9 a4 F7 z" z
  414. /*                                                                                                                                                */; Y& a& b/ }# ?& y+ \$ b
  415. /* This procedure disables the Write Enable Latch.                                                */0 P: Q& ~, ~+ n7 h; |. c
  416. /*                                                                                                                                                */
      ^0 y1 ^% M4 ~! x# P
  417. /* Input:                                                                                                                                */7 c/ `% O: F& D- K$ U
  418. /*                None                                                                                                                        */1 |- K: K! \2 Q% ^; ]* p7 H% e
  419. /*                                                                                                                                                */% ?# w& q' {& {7 O+ L. G( G
  420. /* Returns:                                                                                                                                */3 O6 g: F3 W; R  k8 ]0 @
  421. /*                Nothing                                                                                                                        */
    8 o) P1 d) E* }1 V  O! z( e, m
  422. /************************************************************************/
    % q$ x' Z" x" t) n( U; h
  423. void WRDI()1 l4 Y, W# u1 W
  424. {
    ' p7 Z0 V9 ]' y& i0 s
  425.         CE_Low();                                /* enable device */! g7 L: e1 B" o6 x+ m* w
  426.         Send_Byte(0x04);                /* send WRDI command */
    * ^" n8 G6 A2 Z. p) `) f
  427.         CE_High();                                /* disable device */
    ! `! F8 Q8 b, L
  428. }
    $ k, G4 p" J: A1 t! g' B

  429. 2 ?: ~& B* ?- D  ?0 P
  430. /************************************************************************/2 E" r% ?, P+ X7 G2 D
  431. /* PROCEDURE: EBSY                                                                                                                */; \' `/ n, q8 ^8 |, Y3 l( w
  432. /*                                                                                                                                                */5 X- ^- u6 g) h5 F: G. z0 T, P5 c
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */1 a  N& h: c# q" C; f
  434. /* programming.                                                                                                                        */5 k5 B& l' d1 z) i# q1 e: L/ b/ V
  435. /*                                                                                                                                                */
    ) Q/ f+ H) n; D: S6 P
  436. /* Input:                                                                                                                                */
    : ~. W% }  i. H7 U& L
  437. /*                None                                                                                                                        */
    , A) w1 }6 U2 y& Q6 k! x
  438. /*                                                                                                                                                */
    1 A3 ?) c' Q5 b9 e6 a: ?
  439. /* Returns:                                                                                                                                */$ T! n# c) d! w# p. a0 E& n  e
  440. /*                Nothing                                                                                                                        */
    * @7 K/ _0 M+ P- |
  441. /************************************************************************/
    2 f1 M3 k& G: ~8 Z# _# u3 k+ m
  442. void EBSY()) }/ {% _8 h; r2 G: ~5 [( O
  443. {7 O4 q( y- L! }0 a( W
  444.         CE_Low();                                /* enable device */
    $ V5 W$ j/ x6 M9 V
  445.         Send_Byte(0x70);                /* send EBSY command */
    ' A( X+ t% h) e* ?7 G, G  t2 i# x
  446.         CE_High();                                /* disable device */
    . A( ^9 v5 j7 V' }( k
  447. }) [" G9 B$ }, _8 A9 |( X
  448. ' `. [0 m5 Q, s; g2 \; p) ~
  449. /************************************************************************/
    " {6 V; N7 K2 n# l* d; h
  450. /* PROCEDURE: DBSY                                                                                                                */  O) s3 [+ s4 r  t! K; L$ j
  451. /*                                                                                                                                                */
    9 f; U: v. |" B* }7 O6 Q6 V: v' s
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    ' q" u3 ]* c7 a2 ]
  453. /* programming.                                                                                                                        */
    * M9 P; X$ b; t
  454. /*                                                                                                                                                */1 T( M( m7 X7 r' D7 m
  455. /* Input:                                                                                                                                */
    ; z, F, C- S% R# O; f* b
  456. /*                None                                                                                                                        */
    $ ?$ P! t9 i5 x) j2 x
  457. /*                                                                                                                                                */
    8 P% h% }% W5 C- f8 l1 G$ _
  458. /* Returns:                                                                                                                                */1 z/ V+ {( y7 ~/ Z" V* Z
  459. /*                Nothing                                                                                                                        */
    ) q3 p, k8 ^4 h# K' I9 h
  460. /************************************************************************/$ o  i3 C& Y4 B, o! G6 x+ t; [
  461. void DBSY()0 d" m: P2 [% _0 }/ o& d8 B
  462. {
    0 B0 o- \6 I' a8 ?! S
  463.         CE_Low();                                /* enable device */' K4 K% l# Q- g1 z3 O' `. x
  464.         Send_Byte(0x80);                /* send DBSY command */
    * u/ |2 Q' l, v  U
  465.         CE_High();                                /* disable device */
    5 w) {6 H/ ^& h! y/ r
  466. }
    - b2 Y6 }  C' U5 p7 M0 B

  467.   b$ h$ ]8 d& S7 ]* g+ x% ?
  468. /************************************************************************/& Y, Z4 y4 C, }" e  m) z: t. P
  469. /* PROCEDURE: Read_ID                                                                                                        */
    " C2 N- \: A" W+ C
  470. /*                                                                                                                                                */4 N+ }5 K. b- _
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */( v7 I! x$ y) R! M2 N
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */1 _4 k$ G$ y! P5 j
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    + L, D- y( _( K1 ~0 \# q7 \; M6 s
  474. /* whether the device outputs manufacturer's ID first, or device ID         */5 r- N! B. b! B
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    5 _5 y. f, ^: ]* y
  476. /* variable byte.                                                                                                                */7 O( K4 f4 E5 u
  477. /*                                                                                                                                                */0 a0 Z; ?, B) V1 g" y
  478. /* Input:                                                                                                                                */
    ! X4 g0 n  N5 H; {4 v( Y
  479. /*                ID_addr                                                                                                                        */
    9 T0 w4 |# Z2 \% @+ C
  480. /*                                                                                                                                                */
    # P) _% y" n, N8 ^0 t$ ?8 ^: k5 q
  481. /* Returns:                                                                                                                                */$ Z7 Q: j# r- N% F6 Z
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */# z- v% V" o' ^) {5 W1 }7 Z
  483. /*                                                                                                                                                */
    : l! y& w; v* W
  484. /************************************************************************/) B* L1 A) W3 {8 |
  485. unsigned char Read_ID(ID_addr)
      E9 S/ x) o5 b0 o% T
  486. {/ w+ j4 g9 E( e; m9 Q  J0 Y8 A
  487.         unsigned char byte;
    9 m4 U% ^0 ^% O( z
  488.         CE_Low();                                /* enable device */1 n2 ^- R- w& b2 B+ }6 a1 }$ Z
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */9 x4 w& c0 `: z6 D
  490.     Send_Byte(0x00);                /* send address */
      k' k9 b0 C3 w8 ~0 {
  491.         Send_Byte(0x00);                /* send address */
    3 v* K+ S6 H  |
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
      ~$ n/ |& ]9 u/ T; U9 v3 g/ ?  k
  493.         byte = Get_Byte();                /* receive byte */
    4 e3 O' n+ H3 t6 ~& _
  494.         CE_High();                                /* disable device */
    & X- a0 _9 n+ x: b& ?& U' U: r
  495.         return byte;5 U. c, |- q2 J) I
  496. }8 f3 ^4 o; _! a( P3 I

  497. # ]$ d4 F$ W4 v' {
  498. /************************************************************************/  G! ~3 d, o2 \  X2 X
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */# [& A% d8 ^) n+ e
  500. /*                                                                                                                                                */
    7 K& h" y& C0 ^" w+ Z. f
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    1 }. x' R: P7 x* Q
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */2 ]8 |$ R, K5 R7 [- w0 H# m
  503. /* Please see the product datasheet for details.                                                  */$ d) M- k/ H, X0 D/ }
  504. /*                                                                                                                                                */8 I9 X  c$ S' P% l/ p: B( t" ?6 ~7 S
  505. /* Input:                                                                                                                                */
    ) s/ e! x% Z9 \! ?! t) \
  506. /*                None                                                                                                                        */
    % M6 O* `9 U# L8 d  z
  507. /*                                                                                                                                                */
    & W. k3 v/ o$ w: H7 S  [0 k1 f4 n
  508. /* Returns:                                                                                                                                */( o* ?" z! v, f+ r
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */# ~6 R8 _4 F2 C: N/ E
  510. /*                 and Device ID (8Eh)                                                                                        */. N3 f0 d0 Q" c( R
  511. /*                                                                                                                                                */
    $ A& S" X; k* V. w
  512. /************************************************************************/
    0 }! ~. L+ E) f- E% Y
  513. unsigned long Jedec_ID_Read() 7 f9 l# z$ h$ r6 {* N5 ]+ I. _) Y
  514. {
    6 a' w: \9 P! R+ u. A$ ], ]. A
  515.         unsigned long temp;7 R1 E, D- U$ E& I# p: k
  516.         ; Q- b2 W8 `: ^2 B, S
  517.         temp = 0;) y. w& W8 f/ t2 i' \4 a5 I" x/ E

  518. $ y, b7 g5 U: }6 @! Q6 v+ m" }
  519.         CE_Low();                                        /* enable device */
    + z- G, u; @5 L: M8 G: x% s. f
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */4 |5 v5 n/ q8 [' e
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */' ~' b7 U6 k+ |: ^
  522.         temp = (temp | Get_Byte()) << 8;       
    5 ~* c+ p0 O; r6 j: t
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    ( `  b4 j) N9 \6 ~
  524.         CE_High();                                                        /* disable device */) o# E% C6 S0 V# j* J& t
  525. 7 ~3 h5 q" l( V# E
  526.         return temp;
    . Z  S: f$ V/ |; Y. S5 y5 ^
  527. }
    / c  U; Y6 U% }8 _, h  l

  528. , m5 u) g, |4 W6 K
  529. /************************************************************************/
    ; [3 [5 ^# D  n. F' O4 ~
  530. /* PROCEDURE:        Read                                                                                                        */. L" J: H( D3 u. I9 B3 g
  531. /*                                                                                                                                                */               
    1 b1 z5 L7 z  a6 ?$ N, ?  b
  532. /* This procedure reads one address of the device.  It will return the         */# l8 |6 U& Z. ?
  533. /* byte read in variable byte.                                                                                        */
    : l3 c( n* A* h6 z- z1 K, R
  534. /*                                                                                                                                                */+ S% Z( {6 Q, i# b  X5 _
  535. /*                                                                                                                                                */
    2 s, ^, P) v3 u" c  ^6 f1 |
  536. /*                                                                                                                                                */3 s& U) i- m9 @1 u) Y
  537. /* Input:                                                                                                                                */
    ! z! j2 Q) Z( ]: @
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    4 ]0 p* u0 i% U2 T' l4 K! @
  539. /*                                                                                                                                      */8 ~$ O4 ?( J2 a  `
  540. /*                                                                                                                                                */$ [2 A% _4 d9 q; v8 _
  541. /* Returns:                                                                                                                                */) d% d' n6 A& p* ^" T/ b
  542. /*                byte                                                                                                                        */- F$ t( @$ t1 S" }9 b# z
  543. /*                                                                                                                                                */
    ' y+ b8 Y# @' a$ H6 N
  544. /************************************************************************/) n0 M3 K: H2 Y2 x7 K$ X
  545. unsigned char Read(unsigned long Dst) * s+ _1 H6 n) H
  546. {
    4 i" r: A& |3 z/ R8 h
  547.         unsigned char byte = 0;       
    $ \' C, R0 W0 N( u6 O

  548. 4 j- H0 M8 W7 K% Y
  549.         CE_Low();                                /* enable device */
    ) |1 F: ], J7 }4 c* E$ @
  550.         Send_Byte(0x03);                 /* read command */
    9 m: `! ~8 ^# S9 ~2 U1 |2 x' b
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ( y% T  G% L* E
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));$ _5 u: I# P5 N) }
  553.         Send_Byte(Dst & 0xFF);4 Q: z8 g& T+ y+ I* _
  554.         byte = Get_Byte();  n3 w0 q8 _" z' K
  555.         CE_High();                                /* disable device */
    1 C8 h- G- w/ G9 w+ M
  556.         return byte;                        /* return one byte read */) P- Y% R) s: B) _: D* }
  557. }/ W- W) `8 u3 `/ h

  558. ( a! Y0 W4 d+ K* f% y
  559. /************************************************************************/
    " B. {* }& u- ~& X
  560. /* PROCEDURE:        Read_Cont                                                                                                */8 F: S- V9 C+ g& g0 \/ ]& K
  561. /*                                                                                                                                                */               
    . a, B9 m, K4 d+ G9 s* F
  562. /* This procedure reads multiple addresses of the device and stores                */" }8 d9 k3 W2 S$ ]& L7 i4 \3 V, F5 J3 S
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/; I* b% T4 N: |0 h
  564. /*                                                                                                                                                */5 T; e, J! d! t& D( t# s& Q
  565. /* Input:                                                                                                                                */: v( _1 b# a, D0 b) g
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    , u' o$ h# P/ n& [& J
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */; ~( |$ k: c7 k' {) ~8 M2 T
  568. /*                                                                                                                                                */. B) e3 h; Z* q  [% F
  569. /* Returns:                                                                                                                                */* T7 `; |5 S* U9 |  }3 `( I
  570. /*                Nothing                                                                                                                        */+ u9 R" i  |9 G$ c5 O; p
  571. /*                                                                                                                                                */% ]6 v6 A! h% v2 E# u+ z  L+ R; x
  572. /************************************************************************/
    % s4 k5 w1 o& G* l5 ^
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    - V+ }9 H1 O& U* d. q5 f2 B) @- C! `
  574. {
    * O/ X& f! ], `0 h
  575.         unsigned long i = 0;7 l9 k: U  [, Q6 e* g
  576.         CE_Low();                                        /* enable device */- p3 u0 s/ z. k# r9 c
  577.         Send_Byte(0x03);                         /* read command */
    . ^3 o. k6 a/ o+ D) j
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    9 N. ~: d7 q4 w' L( \$ M! f
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));  q! x8 W0 P0 K0 @- s
  580.         Send_Byte(Dst & 0xFF);! k4 D/ z1 _+ P" U. ~( ]4 z  P0 B
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */9 ]: U5 ~" `! _7 I) E* i
  582.         {+ v( t8 l! S. ]4 @5 O
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    6 G# m8 a1 L3 E
  584.         }0 |3 x$ K* h6 b+ I+ Y
  585.         CE_High();                                        /* disable device */
    # `: v5 f( _& J, n: M+ I+ N

  586. 5 Y% f6 i- D& |+ K& ^( n
  587. }
    4 E/ X4 |4 m) c- S

  588. 7 Q, w- _2 h: f# m4 d
  589. /************************************************************************/$ r: K- ]! K6 L! j
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    ! {: L5 L% M1 t2 _
  591. /*                                                                                                                                                */               
    % a. E+ L5 T  T: T
  592. /* This procedure reads one address of the device.  It will return the         */7 k! n! Q# U& Y. w  y! g8 [. ^. E
  593. /* byte read in variable byte.                                                                                        */
    , ]5 F- A9 n8 l9 V5 R+ q) a: g6 d+ b
  594. /*                                                                                                                                                */
    1 K; a) M4 v/ C" i; L
  595. /*                                                                                                                                                */
    4 P% l2 N& Z0 \% Y3 J) r( `7 G
  596. /*                                                                                                                                                *// l: t  A- `: E1 r
  597. /* Input:                                                                                                                                */6 |' a% ], z4 ?7 u
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    3 V& e3 o# x6 d/ j, m
  599. /*                                                                                                                                      */0 I! @% {  {! |" \% ^% I
  600. /*                                                                                                                                                */
    & C9 c2 a% R; E# j
  601. /* Returns:                                                                                                                                */6 a& @. S9 j! s
  602. /*                byte                                                                                                                        */( H2 O2 |4 W6 q+ S
  603. /*                                                                                                                                                */! X5 a2 D9 c! @% H9 m/ Q% E. M  t
  604. /************************************************************************/& [' l! N1 n1 r% Q7 \) f9 S
  605. unsigned char HighSpeed_Read(unsigned long Dst) 1 b2 R/ Y2 S! k
  606. {
    5 e9 {4 z* f# E7 f. Z& a
  607.         unsigned char byte = 0;        * n% f. v; Q% w7 q- _

  608. 3 O, a* [+ U# Y/ h9 j7 E
  609.         CE_Low();                                /* enable device */
    8 u+ `- y7 ?. d6 W: u4 @. ~  y
  610.         Send_Byte(0x0B);                 /* read command */
    ! \* s" w5 G+ B7 _+ K0 G! t
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ) F5 }* |- O) W6 r: P- T; M
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));* x& p0 S: Q; b2 E1 g
  613.         Send_Byte(Dst & 0xFF);
    " R) [0 o5 ~8 t' }( M$ E- S
  614.         Send_Byte(0xFF);                /*dummy byte*/
    6 S! ^+ v8 {( O( ^4 ~! U
  615.         byte = Get_Byte();4 q( `6 n) l, G: s' n
  616.         CE_High();                                /* disable device */
    . F4 c' a( B. p8 n" _7 i$ y
  617.         return byte;                        /* return one byte read */
    - Z1 i$ J8 f5 I% b9 _5 l
  618. }
    $ ?; d( `1 H0 j3 {6 e7 @

  619. ' i& b  p6 t" D( H" s' p- @
  620. /************************************************************************/
      Y0 n* q5 j  g0 M5 N
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */3 K& `/ v# a4 }
  622. /*                                                                                                                                                */               
    " H+ F7 }7 D5 M0 z4 g) T
  623. /* This procedure reads multiple addresses of the device and stores                */5 }. U/ k6 B& C8 G$ W# Q4 V
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    6 |' g. w6 ?  W* a" c
  625. /*                                                                                                                                                */
    " w3 q& ?8 {/ r5 n) I3 c6 Y! A
  626. /* Input:                                                                                                                                */) c2 |3 X- F) d  J/ k9 R, b
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */& k6 l0 p( _7 s" _* V
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    7 w4 i: P3 p4 U: j- Q6 S
  629. /*                                                                                                                                                */
    , S, q1 u( x- M$ l  N
  630. /* Returns:                                                                                                                                */
    / h  B* N8 o+ A2 Q/ C
  631. /*                Nothing                                                                                                                        */
    * Q+ `" C( A! e0 r; D4 L' N+ U' Z* I
  632. /*                                                                                                                                                */
    ( e3 B! v( o7 d0 ^
  633. /************************************************************************/
    % R: F% l. y. Z# p3 q
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)  ~5 B7 h. y7 V
  635. {
    1 b3 l, t+ a% }6 v6 S  F3 b4 b
  636.         unsigned long i = 0;
    4 e% M  G6 @: c" t& V
  637.         CE_Low();                                        /* enable device *// d$ O3 U6 w) F7 l6 e& R6 a
  638.         Send_Byte(0x0B);                         /* read command */
    : O$ f5 ?  u, H3 }. Q+ z
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */3 G4 ~9 E) f; W: r6 p
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));& x9 e* ]' T  ]7 a
  641.         Send_Byte(Dst & 0xFF);( f! p- H1 Q+ w- h( [4 Q) I+ V
  642.         Send_Byte(0xFF);                        /*dummy byte*/7 j" m  [" n8 a/ P, ^' ?. Y- l
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    0 L4 I  u1 U4 f9 R
  644.         {& L2 r& K6 Y/ I: _% D7 d% z: M
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    - }; ?' M, S+ G5 H5 S9 t) B) Z
  646.         }8 f, e5 u# b' l/ ]# j
  647.         CE_High();                                /* disable device */, h7 J4 h; l- }$ P/ C
  648. }% ^- C" M& K! F0 H" k% A6 e

  649. : J3 l6 M7 O" w: L2 f
  650. /************************************************************************/( T$ i- q" |% B) W5 X/ X
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    4 }' `2 M& q/ ^: q" I7 j
  652. /*                                                                                                                                                */
    ) Y- X8 A& z& p3 p& S  ~( m
  653. /* This procedure programs one address of the device.                                        */
    7 ]$ k+ q# H3 S1 f1 C0 X
  654. /* Assumption:  Address being programmed is already erased and is NOT        */# N. k8 c  ~7 O; z
  655. /* block protected.                                                                                                                */2 ^: ?8 \( U0 r: `8 Z
  656. /*                                                                                                                                                */6 P0 m( C/ l6 _/ [
  657. /*                                                                                                                                                */! m3 S; o0 Q& \: N0 B2 |
  658. /*                                                                                                                                                *// ^! F8 a2 l1 v0 b0 i" O
  659. /* Input:                                                                                                                                */
    , G7 G9 O$ ~& Q( ]; `" {
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + n) j2 D6 a, {7 w) `5 A; G5 l8 |
  661. /*                byte:                byte to be programmed                                                                */; P3 L/ k/ ^8 n) p" M# q
  662. /*                                                                                                                                      */
    5 T# C) d" d# m) g: b; A
  663. /*                                                                                                                                                */
    1 F- Z6 S# v: b0 i8 m2 ?# [
  664. /* Returns:                                                                                                                                */
    6 r0 v" q+ n* m/ C& O
  665. /*                Nothing                                                                                                                        */, F1 b4 w. r+ ]! k
  666. /*                                                                                                                                                */8 z3 N6 ?, w0 y* [* ]3 {
  667. /************************************************************************/
    1 o7 @" ]* X! J, X
  668. void Byte_Program(unsigned long Dst, unsigned char byte)/ n& U* U( a8 l1 l
  669. {
      l  [9 _$ D* I
  670.         CE_Low();                                        /* enable device */$ o/ G8 ^" R1 a9 Q4 [: z  t. f; i
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    3 T4 E+ R8 S" c6 {/ c9 u
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */2 F) [8 \) r3 O( `  f
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));* l! C: x5 Z5 F5 L
  674.         Send_Byte(Dst & 0xFF);' g. x  N) v) D8 p
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    5 B! N7 |) s' t, f/ M
  676.         CE_High();                                        /* disable device */: T8 _4 c, b1 {7 t7 O' ~. q
  677. }
    * n/ z. e' K" W6 h* p1 }  c
  678. 5 t' J1 y. K" Q' N5 E
  679. /************************************************************************/
    1 ~. i. S9 G# O' @. o
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */$ ~6 H: P7 `/ D) H
  681. /*                                                                                                                                                */) n# W* O) A% \' Q2 A6 I
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/9 |4 v9 ~2 e- {9 |
  683. /* the device:  1st data byte will be programmed into the initial                 */, B7 @3 r3 H: p! j, M6 s2 \+ L7 n
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */' A0 @, k! s/ |
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    # G. p/ l6 l) p3 Q8 V. x
  686. /* is used to to start the AAI process.  It should be followed by                 */. U% p' J$ S8 f/ n' |
  687. /* Auto_Add_IncB.                                                                                                                */
    8 v& y! @  t7 A* q" o9 A: _
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    & T' L8 y5 s- W/ X3 c
  689. /*                                block protected.                                                                                */  o, m4 c& k. A! F
  690. /*                                                                                                                                                */
    5 G9 N: {1 Q6 K' t6 n
  691. /*                                                                                                                                                */
    ' S2 _! v: A- p2 P
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */$ M6 i. ^" L5 Y, P8 L% c3 x
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */* l7 I6 P% O: L
  694. /*         unless AAI is programming the last address or last address of                */8 x. X: a2 l* t
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    # k& f3 V7 w9 q1 ~4 |' F; p) s  ?9 t
  696. /*                                                                                                                                                */7 s4 Z3 N4 o4 N) v. L2 q) e, |
  697. /* Input:                                                                                                                                */* l; t, k# W& W# f- c* i! G
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    0 W/ Y8 I( i7 _
  699. /*                byte1:                1st byte to be programmed                                                        */
    " m( H. \3 E* A; `+ e. u8 ]
  700. /*      byte1:                2nd byte to be programmed                                                        */3 Q( R/ N1 x3 J9 `* N
  701. /*                                                                                                                                                */
    ; s( x- K# D8 O, t
  702. /* Returns:                                                                                                                                */
    & `3 m* O/ V( G" p4 h% ^! M8 [2 q
  703. /*                Nothing                                                                                                                        */
    " X1 S1 ~$ h. A' L% x
  704. /*                                                                                                                                                */7 E" a8 o3 R( I" ?7 E$ q
  705. /************************************************************************/
    / ^4 K5 {& m% z; M- K
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ) P, I, `- u; C& _  P# j+ u
  707. {1 G; _& \; Y) y7 H
  708.         CE_Low();                                        /* enable device */
      C+ ?: l$ ~/ S0 V; [; R
  709.         Send_Byte(0xAD);                        /* send AAI command */
    " Y& t5 {: @, y% w: y  c8 y
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */; M$ k/ V9 |: r& U) J. u" W
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));  n9 o- X6 _& L! y  h2 _/ ^' F) d7 `; q
  712.         Send_Byte(Dst & 0xFF);: A' a/ H9 `9 b  D
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    ! s8 M  A! c5 G& ~7 f" V% e
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */3 k5 V3 t$ p, M, k4 x7 a" G; l
  715.         CE_High();                                        /* disable device */
    - R7 ?6 C3 c. o
  716. }1 j1 @, d- Y3 b

  717. - i7 M+ E4 D1 |1 R- u
  718. /************************************************************************// D: Z5 a* x2 E* u0 U9 m
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */9 `! _3 }" V& k! G% _
  720. /*                                                                                                                                                */; m. Y; m7 o% V- b
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/' x6 y9 x/ p4 y$ }. D& C2 H: B
  722. /* the device:  1st data byte will be programmed into the initial                 */
    $ g! r  s7 w7 |$ n1 H' B7 c
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */8 n% `4 G; O! ^" t; |+ P
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    " j5 I0 L; U7 E  {4 t6 D
  725. /* is used after Auto_Address_IncA.                                                                                */- X2 r( a+ {) ~4 z3 U
  726. /* Assumption:  Address being programmed is already erased and is NOT        */" K/ }5 r, I% ]3 ]4 Z: g# n8 W
  727. /*                                block protected.                                                                                */
      i* |" P: b4 _" M; q
  728. /*                                                                                                                                                */
    1 P1 ?. N- Y0 }! I/ o3 ]# P1 l
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */% n; ~5 d2 g1 c; C
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    / B; [, b; J& Q! i
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */1 \4 T( w/ t) p7 Q- d  R: v
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    9 s9 A" V3 C4 x; B
  733. /*         last address of unprotected block, which automatically exits                 */
      }: a) r7 Q0 l  ]8 D: Z) G6 A
  734. /*         AAI mode.                                                                                                                        */3 R: i3 ?/ O8 y
  735. /*                                                                                                                                                */
    : n! @- U4 p* K8 Y3 r4 N% G0 b
  736. /* Input:                                                                                                                                */
    . u* Q5 O# I5 M: T5 J
  737. /*                                                                                                                                                */; j4 c' C/ t1 \; k$ f4 }4 f# T. C. O
  738. /*                byte1:                1st byte to be programmed                                                        */1 q3 y3 n# b( {( {/ c1 Z6 }4 `
  739. /*                byte2:                2nd byte to be programmed                                                        */0 J# A. M5 Y; c: t* n; x+ ]
  740. /*                                                                                                                                      */5 c* U# a0 S( S4 ~2 k
  741. /*                                                                                                                                                */$ v( e2 D, D8 w, `" c$ E3 a! g
  742. /* Returns:                                                                                                                                */  f! h) q4 }: l
  743. /*                Nothing                                                                                                                        */
    , g! t7 C0 t) Y& i% N/ r
  744. /*                                                                                                                                                */; P" j. \8 }5 V$ ?0 h
  745. /************************************************************************/
    % o* T" w& T, [" J: M' c7 ^5 e
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    9 g, z( ?+ W* G: k
  747. {' [$ E" k& F$ Q( W- z
  748.         CE_Low();                                        /* enable device */
    $ g: ^, t& D* T- O' g
  749.         Send_Byte(0xAD);                        /* send AAI command */
      T  G1 d: |1 L# m3 ]
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    4 N. K. p) T# c
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */# F7 B" p; X/ ?3 A
  752.         CE_High();                                        /* disable device */
    + {% c( Y1 J8 Z3 w$ D
  753. }
    8 j) P/ F: |( P* J( H  S! N
  754. & |2 U$ E9 F6 ?  A- E& x. P
  755. /************************************************************************/$ {2 v, e+ z5 ^; d2 T) o8 l% L4 j
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    * z% y; |5 ^  M
  757. /*                                                                                                                                                */+ `* V; g5 T& i6 Y% X
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */. B  g/ g0 b$ c7 N2 B4 b! G
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    - v5 B6 A( S: V' e- B$ i$ ?5 h0 F
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    ' a2 Q3 t8 K" ?% t7 q6 d# b
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */3 Y2 T' O$ s8 Q% c' ]
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */# @" t1 ]# h4 t' g
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */$ |* t" S9 C3 o, ?
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    ) z7 b/ L5 c) a( ~
  765. /* Assumption:  Address being programmed is already erased and is NOT        */# h/ S7 h7 ~7 [2 G
  766. /*                                block protected.                                                                                */
    " i% Y6 C6 u0 J- ?9 L4 M
  767. /*                                                                                                                                                */
    , j4 u; ]3 x8 O$ Y
  768. /*                                                                                                                                                */
    ; B1 A& u) t( g
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    4 n2 |6 E0 B+ Q% u( K
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    , Z8 W$ Q1 z9 x9 ]2 n
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */: k' T7 {. r  ]
  772. /*          to exit AAI mode unless AAI is programming the last address or                */' Z3 d: [" @2 r' K. _
  773. /*         last address of unprotected block, which automatically exits                 */
    * f, w; W( K: k( \! K
  774. /*         AAI mode.                                                                                                                        */
    , ~! y- H2 o9 g3 s, U
  775. /*                                                                                                                                                */
    ( Q& Q/ u& B6 i$ ^4 c
  776. /* Input:                                                                                                                                */. U3 N0 W: i, q9 b8 R
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    " n4 K: B% z1 X* [+ O: }
  778. /*                byte1:                1st byte to be programmed                                                        */
    4 t$ p2 x# t  s
  779. /*      byte1:                2nd byte to be programmed                                                        */
    7 Y+ R" ^: ~: H  F+ G* ?
  780. /*                                                                                                                                                */
    1 y8 ]1 i* \& ?1 W- E) r
  781. /* Returns:                                                                                                                                */3 m5 @$ \+ d- o- r8 g9 ^$ K
  782. /*                Nothing                                                                                                                        */& ]: I3 f; {% y9 r% J1 v; {
  783. /*                                                                                                                                                */! _" h6 z6 l, h1 O" u2 R8 d
  784. /************************************************************************/
    0 _) F) e$ M3 K# u
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)' J/ W3 c2 j0 ?' v0 B, i
  786. {
    & v2 F7 g3 }/ L5 P+ R
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        * H+ m( M3 ?$ V0 _: V
  788. - i* B0 T- C% v9 O
  789.         CE_Low();                                        /* enable device */: K; R6 G; z( s
  790.         Send_Byte(0xAD);                        /* send AAI command */
    - A0 O) @! [: Q' v/ B; k& f- g
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    6 f. C( V% M1 s0 b" N
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 H- H! P" U" i4 ?4 x
  793.         Send_Byte(Dst & 0xFF);
    / r0 q+ {( l% W1 b! \/ M
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    : z$ V% f7 U3 x" q4 o4 V
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */4 A! Y* Y1 E' Y% F+ d  t
  796.         CE_High();                                        /* disable device */
    3 T9 a2 ~2 y0 T2 M7 J, y2 ?( V
  797.        
    * \# b" V& J% f1 |
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */  ^9 d2 `/ k9 y* @' H
  799. ! H! ]+ {6 E# V) K" \
  800. }
    . n) k. ^8 H# x" Z/ L: D7 n+ [9 @

  801. , h) y& i2 ?9 W3 S
  802. /************************************************************************/
      r' _. g+ Y8 J; w3 s( k5 p
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    # `! q6 Y% Q9 K. V( K
  804. /*                                                                                                                                                */
    ' Q/ F' k5 _3 E5 m% j
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */6 U* x2 \! e2 y
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    & D6 p) |4 ^0 R% [
  807. /* AAI programmming is completed.  It programs consecutive addresses of */; p4 ?3 l" \& p$ j
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    3 |, u$ o; Y9 E9 U( z* O
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    ( @! P  Y( @! r  n# U
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */2 u' p- H3 x7 G* J! u- [
  811. /* used after Auto_Address_IncA.                                                                                */
      C& B) U/ g* d; ~( j$ I6 E& [. k
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    ' I7 n9 D" ]6 z1 N( x
  813. /*                                block protected.                                                                                */2 J. `& z! V, |% Q
  814. /*                                                                                                                                                */1 Q6 |1 ^. F9 o' J' U" D" Z9 l
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */% T- Z5 p. S( X7 f% A/ r" i
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */1 W0 \+ T. {( K4 C
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    5 n- `  E; F% r- _5 ?7 R
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    ) o8 b  k" M3 s/ v& e
  819. /*         last address of unprotected block, which automatically exits                 */$ I8 Q( T) j- i; z, P" b
  820. /*         AAI mode.                                                                                                                        */
    2 n5 f3 R8 [; @. T: e
  821. /*                                                                                                                                                */3 \1 F/ b+ ~; {
  822. /* Input:                                                                                                                                */
    - \8 U# Q( H' w+ r# I7 l
  823. /*                                                                                                                                                */% q) F: w# A/ N$ z
  824. /*                byte1:                1st byte to be programmed                                                        */4 U' y3 d  L) t& N/ j
  825. /*                byte2:                2nd byte to be programmed                                                        */& _) \! J& e) `0 X" x6 {8 x
  826. /*                                                                                                                                      */$ d# ^1 ]+ U, j: `; f1 e" U: s
  827. /*                                                                                                                                                */9 C+ B' w) I' K& @
  828. /* Returns:                                                                                                                                *// ~3 I" o; A8 X
  829. /*                Nothing                                                                                                                        */! I! a0 v5 j5 |4 A7 _- p
  830. /*                                                                                                                                                */% M' |: J- j6 D: o! K# @
  831. /************************************************************************/
    * K' ^; F8 G, A# z/ K
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)) ~  a2 d" U5 B8 p
  833. {
    ; P; d: i- z5 H2 G
  834.         CE_Low();                                /* enable device */
    7 H9 {. \# I2 i, L7 i5 H- ]
  835.         Send_Byte(0xAD);                /* send AAI command */
    # W% |& @) U& E; B+ s
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    & J! \: B- P& v, T9 j+ K, O' @: o
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    . ^9 q6 `: |. A. M* V6 M
  838.         CE_High();                                /* disable device */
    & {& M9 {( K4 {& L
  839. ) l, [; u! ?. f: Q1 v( N
  840.         Poll_SO();                                /* polls RY/BY# using SO line */* S- T% I7 v/ B4 Z" E$ ]3 g
  841. 3 ~, b  i+ Z8 e! L+ O
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    . J- S6 Q7 c4 `
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    * A" {1 e# I  q: e" g. |
  844. }+ [  q  a0 S( j0 K! S6 P, u

  845. & {% M/ H2 |( J
  846. /************************************************************************/" t; b' U$ D) F/ W3 `' ], H% B
  847. /* PROCEDURE: Chip_Erase                                                                                                */) H" _, M; @- x1 |
  848. /*                                                                                                                                                */
    8 b6 |9 Q* R- z: j; x. x0 F
  849. /* This procedure erases the entire Chip.                                                                */
    . g/ |% |* ]5 S- Y2 c
  850. /*                                                                                                                                                */' E) Y( n5 L8 A, v1 H- L
  851. /* Input:                                                                                                                                */
    ; g3 {8 ]( c" d( H3 C6 t. |
  852. /*                None                                                                                                                        */
    / r4 n. V  @2 F+ {
  853. /*                                                                                                                                                */
    ) x3 R% v# G8 U. _" d8 \+ B
  854. /* Returns:                                                                                                                                */
    7 N0 V& K. S2 G1 q- \# V1 v, U1 ^
  855. /*                Nothing                                                                                                                        */
    9 I, B8 G: U2 \3 H+ J" c, [% ?
  856. /************************************************************************/- U: o* ?0 E% i+ k3 q
  857. void Chip_Erase(). Y" w/ B7 a4 `6 g# Z2 Z
  858. {                                                  f+ F# y7 B1 P
  859.         CE_Low();                                /* enable device */
    + @& S; o9 ]; @7 U. E/ p
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) *// B6 C2 a6 c( {$ ?! g
  861.         CE_High();                                /* disable device */8 S0 c5 C$ F! q1 [5 `, |
  862. }
    . D9 I6 W  q% J/ }

  863. ! W( ~1 F7 K5 C: P+ ?
  864. /************************************************************************/; E+ f7 Y: G3 n& j- i
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    0 O" g5 U' |! \8 W, k* n2 ?% y
  866. /*                                                                                                                                                *// [+ Q& J) p2 f
  867. /* This procedure Sector Erases the Chip.                                                                */
    9 |0 A  n5 ?* x7 o. @# z8 R: S8 M
  868. /*                                                                                                                                                */  \# j- \& B0 T. N. K
  869. /* Input:                                                                                                                                */
    6 W3 |# C( n% j0 m4 s1 R5 ^0 ?3 x
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */( K9 ?# L8 i2 [6 ]4 o
  871. /*                                                                                                                                                */7 _% U, P+ T5 G5 {& H4 ^. X
  872. /* Returns:                                                                                                                                */
    3 S$ Q" `, V8 K5 g6 V; J/ k+ q
  873. /*                Nothing                                                                                                                        */% ?" W8 |6 L  I
  874. /************************************************************************/
    , T. h4 ]: x. W; r, @2 I+ B& s  k% F! i
  875. void Sector_Erase(unsigned long Dst)
    , R" f6 K( t: S) A/ `
  876. {. u6 _4 b# h# f3 v- c& H: S% k2 x/ E
  877. 2 f) @$ V* H2 C" Q  W
  878. * \, w. y9 O% ^9 t( I
  879.         CE_Low();                                        /* enable device */6 k* P/ Q) {! P
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    + L" c: k- x$ {
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */' }, Q. Z2 @+ O4 ~! |
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ; r3 e: Z9 r* k" j+ J3 _( n
  883.         Send_Byte(Dst & 0xFF);
    4 P+ \5 ~  T( m& m
  884.         CE_High();                                        /* disable device */0 j* d; w: f+ c! G9 D' L
  885. }        # g, j5 \8 w' R3 z8 p
  886. 3 r+ G% P6 w9 b$ z7 x& r+ A# C
  887. /************************************************************************/
    6 Z4 O/ [( w- F! V! O; Q
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    : W7 f- }* c7 v1 x/ @1 E
  889. /*                                                                                                                                                */* W9 h3 m4 a* ~9 y. \% d; W
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */( L0 F) }1 Y9 O, [$ f
  891. /*                                                                                                                                                */
    / `& `$ @0 H3 i/ `" y$ n9 Z* W' b5 [
  892. /* Input:                                                                                                                                */
    , Y1 r: o: C4 F
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */& r" v) z! y! I( m" t
  894. /*                                                                                                                                                */! O  o. h& p/ B
  895. /* Returns:                                                                                                                                */; C8 I- n0 R4 I
  896. /*                Nothing                                                                                                                        */, N- I3 {' d& e" a2 I$ M& Q
  897. /************************************************************************/0 g. X2 l( q$ {6 l
  898. void Block_Erase_32K(unsigned long Dst)' G# \  P9 [. t5 Y) y1 H  K
  899. {4 _1 J2 Z( R; i6 Y) b
  900.         CE_Low();                                        /* enable device */
    5 L, ]0 u% ?' h8 G2 d" a" h- M9 E
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    ; I  T9 X5 t6 v3 x0 T2 l4 P
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */4 r: @. h7 K& A  A$ P7 n, J, d* Z
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    7 K# W/ O$ O4 z+ [, U
  904.         Send_Byte(Dst & 0xFF);
    ) v& u7 `- p6 O  q
  905.         CE_High();                                        /* disable device */
    / I8 d# X/ m: l: X. \
  906. }- Z  W( R7 @6 S5 W; T; u% Z
  907. , @/ C$ d5 y/ L6 t3 Q& x  I$ B
  908. /************************************************************************/$ i9 }/ [7 `5 g% e' m5 r. a, A) R
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */7 _/ x& o& \" B2 ^+ D
  910. /*                                                                                                                                                */' K; R: |8 D% u" T
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ' f$ {( e" G3 B
  912. /*                                                                                                                                                */! u) @  [& `2 w2 Y; X
  913. /* Input:                                                                                                                                */0 {$ q* F$ [( o* _9 t
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    8 m5 r: d" }6 Y1 V  c2 M  T
  915. /*                                                                                                                                                */5 Z! F/ n% ]2 c8 W. I, |
  916. /* Returns:                                                                                                                                */
    $ e; e7 b. L4 k8 _4 H
  917. /*                Nothing                                                                                                                        */: B8 ~% e1 E  Z8 T7 B* u4 \+ Q
  918. /************************************************************************/: B3 n$ L5 D1 x7 k$ F& f+ l% u
  919. void Block_Erase_64K(unsigned long Dst)
    9 E: k2 p8 ~7 o6 S5 \% B' Z
  920. {
    . J  z) e4 E; Q* w4 ^. g" W
  921.         CE_Low();                                        /* enable device */
    / P8 \% ^9 j. p! d) |8 Y' |& \
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    " z2 K4 v- v/ c7 f" }5 B, W5 {
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    $ x% k  P! E% c* n( j  [
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));! s# \& d, Q( v1 g
  925.         Send_Byte(Dst & 0xFF);
    7 W6 G+ c. F! |& p, u5 t- c
  926.         CE_High();                                        /* disable device */
    ( g! G" A2 _: j7 R
  927. }. s0 o% x3 U) a# a/ M

  928. ; Z# n* p- K) R9 V* F+ `+ p& f
  929. /************************************************************************/
      I1 t1 v0 d$ G8 M
  930. /* PROCEDURE: Wait_Busy                                                                                                        */: p$ P* X1 M; y: c; C
  931. /*                                                                                                                                                */$ q9 l/ o+ o+ Z% p; k
  932. /* This procedure waits until device is no longer busy (can be used by        */: E# c( N4 ^" t- X7 Q* W
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */4 F; X8 Z( K4 J* j
  934. /*                                                                                                                                                */$ q4 k8 U: n+ h" Y! j
  935. /* Input:                                                                                                                                */- N; F5 f& m( T# z$ ~) j
  936. /*                None                                                                                                                        */
      p# ], e# [9 T( t4 ^& S
  937. /*                                                                                                                                                */
    3 M; @) R, b6 |& I! d' ~
  938. /* Returns:                                                                                                                                */0 [/ B1 A, N8 o( R; y
  939. /*                Nothing                                                                                                                        */
    : J0 _, r2 Z# }, J- Q
  940. /************************************************************************/) j8 \8 h# v/ O! x
  941. void Wait_Busy()$ z1 d2 J6 \% E  A
  942. {$ v2 m0 Z! M* z8 m' u
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */1 o8 {9 ]. Y4 ^" m& h5 m
  944.                 Read_Status_Register();
    $ L2 ~, m$ X1 o
  945. }
    8 F7 z+ a" e1 v9 G+ M6 z2 h1 d  ^8 R
  946. % G. R) l6 a9 {
  947. /************************************************************************/8 Z1 u8 F- ^2 ]
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    ( n. z) H4 z8 m; f6 e$ Y. u0 N
  949. /*                                                                                                                                                */8 ^5 I4 G) [- z# B: F! @
  950. /* This procedure waits until device is no longer busy for AAI mode.        */6 t6 D8 g% ^; G  l; @( R7 h8 }7 T8 F
  951. /*                                                                                                                                                */6 e2 b$ |. }8 q1 k! Z2 c7 e! e( N8 A
  952. /* Input:                                                                                                                                */  h& j' [; z3 [
  953. /*                None                                                                                                                        */. L3 |. N& j% T0 x" e- f
  954. /*                                                                                                                                                */
    $ g) E& ~: x, g1 e
  955. /* Returns:                                                                                                                                */0 b; ^" |, ~/ h, s
  956. /*                Nothing                                                                                                                        */
    2 l0 R$ A) c3 S
  957. /************************************************************************/
    & O7 _. b( D& h% T) g$ N
  958. void Wait_Busy_AAI()
    : g" H6 @1 h1 y9 W" z; }& I- r
  959. {
    + X- o: {# N8 u; `
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    7 K' p# |( t% r5 ?( w
  961.                 Read_Status_Register();
    # O& A4 \' j' ?5 r' [8 u
  962. }
    7 y3 q7 g4 s# W  o* r% L
  963. ! a3 ?) \2 |/ D& L& s  d
  964. /************************************************************************/7 |( `0 F$ @6 t- P3 j+ R) _+ \5 B0 V
  965. /* PROCEDURE: WREN_Check                                                                                                */
    : {. _& P# w+ q
  966. /*                                                                                                                                                */5 c- v7 b3 ]& J! d0 W
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    % E" s+ ]& ^3 U: f5 Z
  968. /*                                                                                                                                                */
    , N! D8 H5 p- n5 o  p6 w% t
  969. /* Input:                                                                                                                                */
    1 ?8 g; M" A2 }) n
  970. /*                None                                                                                                                        */0 ~/ O" h- D0 X6 k, l
  971. /*                                                                                                                                                */
    ) F( u) u4 D7 _/ R) S
  972. /* Returns:                                                                                                                                */+ L3 s2 H$ C- C% g! c
  973. /*                Nothing                                                                                                                        */
    4 x8 p" i5 f' u; P2 m3 v; P+ l
  974. /************************************************************************/
    + w( H$ v$ E; I4 O5 M* S! S1 y  X* z
  975. void WREN_Check()
    6 Q8 U+ l* [1 l' u
  976. {
    " x1 e0 p  \9 |! y
  977.         unsigned char byte;
    5 G2 e$ @! j; [  b
  978.         byte = Read_Status_Register();        /* read the status register */, R6 m* N4 X- @! L
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    ; N$ D2 {. z9 b' B/ w
  980.         {/ {, f/ R" }% i+ U( _
  981.                 while(1)
    1 k9 z: Q4 [2 k5 K( P9 l
  982.                         /* add source code or statements for this file */) c: U8 l% V# @& E* s  G, V3 Z
  983.                         /* to compile                                  */0 w: `/ p0 b, t- z. v1 U. g% y  A
  984.                         /* i.e. option: insert a display to view error on LED? */$ a( ~# b3 m# j
  985.                  9 Y9 b' G4 B0 F
  986.         }
    ' B5 T6 _' R/ J  Q2 T6 ]7 q
  987. }, Q8 }2 V8 _5 Z- a

  988.   v" T% n  s) F8 q4 U- h9 T6 R/ c
  989. /************************************************************************/
    % Z+ R: I4 i! l& g# ^5 M
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */5 J3 E7 u6 _4 t
  991. /*                                                                                                                                                */
      x6 A. _8 U! J. c* |& X
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */2 l7 R0 x5 E  V" |: N
  993. /*                                                                                                                                                */! m; p, F: |# _4 W: q8 t
  994. /* Input:                                                                                                                                */7 q( F7 G' w6 O0 L6 Y# h0 }
  995. /*                None                                                                                                                        */( f0 g* j8 M2 s1 H% z. d2 B
  996. /*                                                                                                                                                */' h/ O/ @# ~2 u; {% [: E7 p
  997. /* Returns:                                                                                                                                */8 x7 |* p# T+ D* q6 u5 ~! j
  998. /*                Nothing                                                                                                                        */" W( ~/ g5 e) M, {9 g  n! r' T
  999. /************************************************************************/8 A8 f" w* R$ T  M3 k+ k7 Y5 ?1 g
  1000. void WREN_AAI_Check()
    7 I. _7 m7 o! L; H4 W2 W- A
  1001. {
    , _1 I4 X# E$ D$ Y
  1002.         unsigned char byte;* v3 F7 n7 J1 q) J0 L
  1003.         byte = Read_Status_Register();        /* read the status register */) ~/ V% c0 F/ }6 C! ~
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */- N6 v: n6 k- T6 [
  1005.         {
    : v7 e, E7 V! Y" u" W% ~" {
  1006.                 while(1)               
    " o1 ?: l: p; a+ S2 F
  1007.                         /* add source code or statements for this file */
    ( g9 M3 @0 \( u9 @
  1008.                         /* to compile                                  */
    + u/ `/ R4 y/ B8 Q/ }# ^
  1009.                         /* i.e. option: insert a display to view error on LED? */
    : K$ ?6 V0 B* k) w- H
  1010. % Y7 A. `9 M! U' V& @( p
  1011.         }
    & ?9 V2 ]; c+ Y  n. h/ L1 G. g: c
  1012. }4 ~6 {7 F- h# C  C0 ]

  1013. ( W0 C4 O" x6 Q- `$ ], _! h! [6 v: b
  1014. /************************************************************************/; `/ ?! z- z' ^
  1015. /* PROCEDURE: Verify                                                                                                        */7 f. Q$ w, {- M: U1 q7 T/ g
  1016. /*                                                                                                                                                */
    $ G* e  ]; z) Z
  1017. /* This procedure checks to see if the correct byte has be read.                */* _  w3 T- M: M& I
  1018. /*                                                                                                                                                */
    7 Y' Y4 v1 j# q; _  L& F4 x! t
  1019. /* Input:                                                                                                                                */2 [8 K6 l1 c, g, Y" H. L
  1020. /*                byte:                byte read                                                                                        */8 k7 y4 d/ d$ s4 n- T4 o
  1021. /*                cor_byte:        correct_byte that should be read                                        */* F+ C1 C" W/ C" u# I
  1022. /*                                                                                                                                                */
    + x  [8 [  V. C5 _: I
  1023. /* Returns:                                                                                                                                */
    8 x. A1 g5 M) \( x! @
  1024. /*                Nothing                                                                                                                        */
    9 [6 ?& Z3 L" i  _! z+ @3 [
  1025. /************************************************************************/( z) p$ t$ ^/ e- c  F6 {2 K
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    . J3 n' Z$ R5 X$ f
  1027. {& _* v  G. C, N5 y$ K  V1 J
  1028.         if (byte != cor_byte)0 ~& f  B, b. b; ?* D0 o6 f% k
  1029.         {( o  S7 j4 O/ A! n
  1030.                 while(1)4 K& _' \: y' U3 k, |
  1031.                         /* add source code or statement for this file */6 k4 I/ V8 y& x; O
  1032.                         /* to compile                                  */
    4 R, d; Z' G) L: `, D9 d9 g0 Z
  1033.                         /* i.e. option: insert a display to view error on LED? */; r7 `1 k  [. U5 i: [
  1034.                
    + ^  ?5 M/ A# C: i7 [+ j
  1035.         }
    ! ^# T/ x1 r4 c& _& ]
  1036. }' M/ f1 i. i9 C6 b7 A
  1037. 4 z) F( K' `4 B, O0 Q
  1038. 5 ~( C9 o/ A  V) ~
  1039. int main()
    ' u  I9 S! T0 \# v( t
  1040. {
    & _, N& q( I6 t( m6 O% K, J
  1041. 8 I* g3 x6 a& G% u8 b0 O- o
  1042. return 0;
    6 n& R* M& n/ H5 s
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:; D$ ~5 ~0 j  M& E
   main()8 s( _5 ~7 R; D7 h, g8 q  Q
   里面怎么是空的呢?; b6 u, q; _: I4 J$ B! ^1 S2 ]( |
   发一份给我吧
7 n- i. I% _; ^* e) a6 Smail:luyijun2005@hotmail.com: m6 d5 y/ b+ H" o
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。1 q7 M: w) s6 _9 G3 _
# N+ v" a9 g: k' {& k* i1 k
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。3 J' Z3 K( @3 f  Q/ y- x- q2 l2 v
EC的代码在哪跑,你看DS的说明,每个EC都不同的。
  j" {5 ^* V9 L1 O' fOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
: I& S/ x1 R$ f上面几个问题是你没看任何东西而白问。
. N1 K# r/ R9 {; H; f: S; V4 |7 v+ h- W' x) y
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

9 f' b& H9 A0 v  Q% S8 X关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
1 X, L/ R" e% T
# F! A. p+ m  d; X关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”2 K# j, ?' G0 R" d# U  K2 @
& y0 I. U& w. s' i3 H4 q2 G
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...3 I( _" x( N* S$ C# [: m

1 C6 |4 O, _( j$ k5 O/ ?8 j+ M不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样1 x/ V* Q- r' O* J% p; S
似乎要把SPI能support 到最大,这EC chip应该有好卖点
# }9 o9 v9 P1 c) UBIOS功能要不要强大,也就决定了SPI Flach的大小
* H7 d& j+ [9 z: R! L我是这么想的~让OEM去决定要挂多大!
' y* o  Z1 ]# F# B# G如果我司有BIOS工程师就好了~哈
% v% ?& G5 ^/ F- u2 t' s9 FWPCE775应该算很新的东西,来看它支持到多大?
% o  o8 ^) q+ }% K8 |- j1 h' I( i* w6 x+ j; U
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte9 f* G0 b! a- q. ?  `9 g
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码." h2 `; T) F" r# V. ~3 P# W

3 l+ T7 c; u2 Y5 o- ^3 N这份driver收下~希望以后有用到5 Y: l7 r) [0 ?4 ]
谢谢bini大大
2 G% \0 u+ k5 i; v6 N5 X' j4 B2 u4 g5 B) u. N. H& n9 e4 _2 s
很新很新的新手,如有错误请指正 (准备看第二家的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()
* n* S% N! l$ ?3 }. W- D{1 I5 x6 h! w% u$ T! |
        unsigned char temp = 0;) P: v; a* ~/ Y7 N$ O3 [  d
        CE_Low();2 ^, O; n4 a$ G+ z( x0 q
    while (temp == 0x00)        /* waste time until not busy */
1 a3 y! B  f" z$ c" C  t% \                temp = SO;! [3 ]: h- X2 h' i% ]7 Q) t. V: n; _
        CE_High();
  P/ X7 R* O. h! L& W! t# c3 q; W}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)' W! A' k8 l2 ^$ p
{
7 q* E% Z* [) G+ D; }        8 |# E' f3 \8 L/ A
        unsigned char i = 0;
/ g: g' k8 y0 Z) X: G/ i        for (i = 0; i < 8; i++)9 ]4 ^5 L# h2 R4 H) n$ k
        {
9 q6 _  P& e( ^5 N               
; b* a6 [6 E( f4 X& X, T* ?% v4 a                if ((out & 0x80) == 0x80)        /* check if MSB is high */
2 @( g6 a; }$ t/ i7 Y                        SI = 1;. C/ o7 y  y) l) g$ \$ H) x
                else
; q6 [0 k; I- R3 N4 x                        SI = 0;                                /* if not, set to low */
. {2 B+ {# \* `; Y( \ 问              SCK = 1;                                /* toggle clock high */# K: z& J: f; }$ ?6 o
   题            out = (out << 1);                /* shift 1 place for next bit */
1 O2 R0 [) }$ L! v' g& s                SCK = 0;                                /* toggle clock low */
& G( s% ^* o* B9 Y0 _# y        }
7 C5 n/ d! d9 a3 M" f}
' n3 _/ C: I4 ` 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-4-19 22:08 , Processed in 0.045959 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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