找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54199|回复: 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 Driver6 ?3 w: @! h/ T, G

  2. 4 u* ]0 i7 M, [$ o2 v0 z/ U
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory7 b2 u9 g4 _; F0 n2 o9 s
  4. * Y: ~- [: G2 e! y
  5. November 4th, 2005, Rev. 1.0; w* z0 N4 x0 r) K, Y8 {+ k" d
  6. ' C( n3 e! \6 F( T5 e$ @3 z
  7. ABOUT THE SOFTWARE4 _; ~# W4 [# b& z3 Z
  8. This application note provides software driver examples for SST25VF080B,4 L% a; w0 g$ J1 X  P# ^: r
  9. Serial Flash. Extensive comments are included in each routine to describe
    % v  m& A: P  ]6 K: r3 M# B6 j8 x; p3 l
  10. the function of each routine.  The interface coding uses polling method
    * N; c- Y( U% J0 w
  11. rather than the SPI protocol to interface with these serial devices.  The  G0 Q# n& I3 b
  12. functions are differentiated below in terms of the communication protocols% i* a: ~- X9 G6 T
  13. (uses Mode 0) and specific device operation instructions. This code has been 6 U: T2 b- L& b
  14. designed to compile using the Keil compiler.! T/ v$ v. i' a

  15. 1 H/ c1 }& G* r1 {1 s5 O0 A- Y
  16. + r' H! F$ v- S5 N8 l) v" y
  17. ABOUT THE SST25VF080B/ R$ X' b6 |. m$ c, M. O

  18. - U  n- b5 `( S7 L
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    $ n/ u/ |3 I6 |% B1 u: H+ s
  20. conjunction with this application note for a complete understanding
    - f, t0 @3 ~' W( E, K4 H
  21. of the device.: C! D7 p+ g3 z) z# v5 U) y' L
  22. 4 u& j# v- Y$ k) i- w% T$ ~

  23. 6 c& o& |. ]1 n$ ^+ N6 y
  24. Device Communication Protocol(pinout related) functions:
    % w6 M# t& ~7 O
  25. . N' b2 M8 D; `6 j' A1 X
  26. Functions                                    Function. P, q. Q. E0 ~) n8 H+ G7 w0 `
  27. ------------------------------------------------------------------
    " R# A, x8 k& p
  28. init                                        Initializes clock to set up mode 0.
      }. T+ n/ `# y  Y- P: R1 k* @4 H
  29. Send_Byte                                Sends one byte using SI pin to send and
    ( C6 r' c6 T% }) S
  30.                                                 shift out 1-bit per clock rising edge& j. U6 I. a1 N/ e/ ^5 W
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    1 \5 Q; w/ K0 u( M: W  r0 Z8 Y$ O
  32.                                                 in 1-bit per clock falling edge
    8 E! v$ K9 S0 |- N: K
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming6 ?4 l: q# s4 |; m$ f
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    % P) m6 ~& n' O5 k  E
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    , n2 _. T* G/ E5 |
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    3 m5 A7 D: t4 }6 d# Z
  37. Unhold                                        Unholds the serial flash
    8 }. [! h- l3 y. i( S
  38. WP_Low                                        Clears WP pin to make serial flash write protected* a) I8 {3 H: Q% g, I
  39. UnWP                                        Disables write protection pin
    : J) J# N& |3 J( Y7 m
  40. ; b9 l8 I9 |3 Y
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    4 K$ c6 U' j# x- I+ V, T
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your% ?8 i0 u9 V; A( H' f
  43. software which should reflect your hardware interfaced.          / v) O2 j; d( ?4 d# Z, E6 `5 X# Z
  44. 8 `+ C; l3 i0 Y9 O4 b7 I7 M2 k+ H
  45. - a1 O/ g  T1 a8 r
  46. Device Operation Instruction functions:
    / [  |) Y( x2 d$ k2 V! T
  47. * S, G" h- r6 d0 O0 x
  48. Functions                                    Function' U. K4 T1 ]9 S
  49. ------------------------------------------------------------------
    8 B% \& ^, m6 j- y5 p% Z
  50. Read_Status_Register        Reads the status register of the serial flash
      J6 |5 {6 O0 Z) X: @6 u' o
  51. EWSR                                        Enables the Write Status Register
    . \- p9 L8 e( M* ?+ s
  52. WRSR                                        Performs a write to the status register
    3 Q1 x9 X2 ]0 N: z" i. s
  53. WREN                                        Write enables the serial flash
    6 H# f7 @  G7 Q$ K# G4 X
  54. WRDI                                        Write disables the serial flash
    3 Y4 j% @3 Q0 q4 l9 {
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming! V5 _8 |* o* J' T% M! {* c
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming! j) k0 H/ K# v: B/ A2 a0 {7 b
  57. Read_ID                                        Reads the manufacturer ID and device ID: b- {+ X7 O8 F  k
  58. Jedec_ID_Read                        Reads the Jedec ID
    8 b5 M' q( b# V5 J8 U
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)7 t) j6 j& H! a, }1 {5 H$ B& b/ M
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)1 O9 g0 }1 A# q! H/ H/ Z. x# i; L
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    6 P$ D" T/ g5 Q4 `- ?
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
      N' Q9 V: _  _6 C; u8 [
  63. Byte_Program                        Program one byte to the serial flash
    / A$ D: C& u+ f) N+ l% p! _
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    8 O3 H6 z+ d% G
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    2 y& f9 [' u) }* v
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    , s) T7 Y) X' d5 |: S6 p
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY- @+ N7 c# X/ X9 L. F: ^3 W
  68. Chip_Erase                                Erases entire serial flash
    ) S1 `! M( h9 l8 g- _
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash7 R* I( ~8 ^2 U
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    , O$ o, Q7 I! Y6 e+ ]; X; x
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    1 ]$ Z) `, F( Q! ]) ?/ h% S
  72. Wait_Busy                                Polls status register until busy bit is low& v/ i4 N. U* b& B2 u
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming! @2 l+ K. |! j% W
  74. WREN_Check                                Checks to see if WEL is set
    $ h: N2 o. E/ [" _# j
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    + G7 G1 y/ ]! A# c
  76.   _5 G$ }5 Q" g- S
  77. / L( b) C9 P1 _  F1 u! ^/ ]0 Y# n
  78. $ S# h1 K( F" E* ^
  79.                                                                      + ~, e- [) H' s
  80. "C" LANGUAGE DRIVERS " B  i7 B2 `; b- l
  81. " Y  W8 x" V" l
  82. /********************************************************************/6 F% c# [5 Q" J
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    % a& c3 ]# x! h; L: p
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */9 p( H1 P1 T# X" g$ J/ {) w' Z
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    ! [7 i' q. A! g$ c- g; x$ w
  86. /*                                                                  */
    & p/ J' s9 O: x
  87. /* Revision 1.0, November 4th, 2005                                                                          */   ; ^% n) Y9 r) S8 L
  88. /*                                                                  */
    , i0 H4 w( u. ?( r& h
  89. /*                                                                                                                                        */
    " Q$ ^; v  j& R' {" u- p7 o$ }
  90. /********************************************************************/
    7 _/ |5 r0 T% J0 Z. r& q( s/ g
  91. - o; e/ _: t3 ]! Q7 K
  92. #include <stdio.h>) N$ H8 L" @( U8 C1 c
  93. #include <stdlib.h>, ?7 U- K0 p: K, F) G" F$ I* }
  94. 2 \0 ?' X7 O1 `. e. Q
  95. /* Function Prototypes */
    ; V/ s, s5 U: Z: E7 f
  96. 4 T/ W, Y9 ~2 j
  97. void init();
    " i$ ^. D, ?9 i: E0 h0 h# V& m: w
  98. void Send_Byte(unsigned char out);
    , i. E  X4 n. i
  99. unsigned char Get_Byte();1 {1 Q- t3 j  m. ]8 ~
  100. void Poll_SO();
    " i8 X0 R2 I" k$ p# y
  101. void CE_High();  u( Y) q6 r) `. ?8 @
  102. void CE_Low();9 _& H( ^) T9 |
  103. void Hold_Low();
    6 X  m- _  p: q+ N( Z  w  c4 w) u
  104. void Unhold();6 A' e% K# ^: D8 M
  105. void WP_Low();
    . |0 J" x0 Y! I8 n& r$ d
  106. void UnWP();
    - S7 A) P" o% G4 v% r
  107. unsigned char Read_Status_Register();
    : s7 n4 W" ], R
  108. void EWSR();" {" ?: M* o( n& x) p% H0 O
  109. void WRSR(byte);
    ! P5 \* K7 O1 B" V
  110. void WREN();8 G0 x6 `: U8 I4 p
  111. void WRDI();1 k- o  l4 M- B5 e
  112. void EBSY();
    ; l% t/ N1 h" R
  113. void DBSY();# a' U" s; Q2 G) I* d) r
  114. unsigned char Read_ID(ID_addr);
    " W% |3 E0 {( _" \
  115. unsigned long Jedec_ID_Read();
    4 v  C4 e$ t7 [6 \
  116. unsigned char Read(unsigned long Dst);5 Z. b3 }- G3 \' b) E+ W
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);7 t$ L4 I4 q* Q% K0 L& L2 a3 q
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    $ M7 d% R. Z: S' S* s
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    - H; O: W6 k& u0 d/ a
  120. void Byte_Program(unsigned long Dst, unsigned char byte);5 o9 P0 I% Z8 X  T3 {& H5 }
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);' `6 ^" Z7 e9 t
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    $ `/ \! p! B  a& K8 O+ A
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);( z) m( [9 R" Q/ f5 a
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);0 m  f9 Q8 b7 \, I
  125. void Chip_Erase();* r8 h' n- L, ~- N/ S
  126. void Sector_Erase(unsigned long Dst);- D+ M4 t3 z( S! l4 O
  127. void Block_Erase_32K(unsigned long Dst);
    " ^& j/ G% K- y. `' ]
  128. void Block_Erase_64K(unsigned long Dst);; E9 a, K1 q. T! |! _4 W, \
  129. void Wait_Busy();( ]$ r. {- X" |: @6 n
  130. void Wait_Busy_AAI();7 K# N4 n- E0 D0 ^1 l
  131. void WREN_Check();
    1 \& A0 d' ~% l( @! e
  132. void WREN_AAI_Check();
    / i% n1 `( i/ T  D0 C/ z
  133. 3 q1 @" ?2 X6 B4 q1 s: D
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    ) s. A/ y$ c, w/ c$ x

  135. ) `1 N1 {: D3 u' P
  136. unsigned char idata upper_128[128];                /* global array to store read data */3 B' h/ [: c! }* f4 b4 z6 t
  137.                                                                                 /* to upper RAM area from 80H - FFH */- B0 o+ t0 G. _/ `; n  N
  138. 9 `# V$ T; d9 t0 _, }8 P
  139. /************************************************************************/( G" H* y4 N: g2 F2 D' \7 z
  140. /* PROCEDURE: init                                                                                                                */
    8 n: A; n  g8 A. @- Y0 }* q% e
  141. /*                                                                                                                                                */" s  T" y- m& v* P9 O  ?
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    " w% R4 x( H( o" @$ ?
  143. /* setting up mode 0.                                                                                                        */5 z0 f% b3 A% w5 a
  144. /*                                                                                                                                                */
    * M" x% Q4 @/ e& L' P. c
  145. /* Input:                                                                                                                                */  X; ?' v$ ?$ q) a2 Z
  146. /*                None                                                                                                                        */; B) U) n1 P" }
  147. /*                                                                                                                                                */
    2 T3 [& C6 ~7 B( A
  148. /* Output:                                                                                                                                */+ B4 s; a; x* h
  149. /*                SCK                                                                                                                                */4 ^! x7 g. l! e  O$ E9 l' L
  150. /************************************************************************/" X8 U4 K* n1 Q# o
  151. void init()
    % z5 u+ y0 l' F2 ?# n  p& C
  152. {- A/ t: D8 D  k+ u0 ^! Z
  153.         SCK = 0;        /* set clock to low initial state */. S+ U% q8 D( e) k: J/ ^
  154. }
    " I. E/ c3 c6 H$ d/ @" V
  155. $ Y" d; _' |: Y: F4 B0 X! ?
  156. /************************************************************************/
    3 ?) _$ C+ x. c% R$ b2 G$ |
  157. /* PROCEDURE: Send_Byte                                                                                                        */: @2 y! V$ Y- h. ]; n
  158. /*                                                                                                                                                */
    $ d* ^  u) i* J2 E7 w
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */4 B% N! W( }6 d' M. h4 |
  160. /* edge on the the SI pin(LSB 1st).                                                                                */$ o3 L* X5 d7 n+ K+ N' ?, x0 p. x
  161. /*                                                                                                                                                */7 u5 |1 X4 |- A- I7 @8 S( @3 V, x+ ?
  162. /* Input:                                                                                                                                */) l" a. N+ R0 M' c
  163. /*                out                                                                                                                                */
    " _  G" f, ^# h5 X! k/ ^
  164. /*                                                                                                                                                */  @% b# D1 g0 [! F. \+ _" w  W
  165. /* Output:                                                                                                                                */
    1 _7 R# F& Z4 u+ K# a
  166. /*                SI                                                                                                                                */
    + P8 h# Y9 p" c) T9 R( O6 M
  167. /************************************************************************/
    ; }0 n% }/ r0 b1 g
  168. void Send_Byte(unsigned char out)+ g) @# v% I$ u) B
  169. {2 S1 w: _) x( T
  170.         - s2 q' e$ }" F! q% R2 U/ j* S" v
  171.         unsigned char i = 0;/ _5 t' y. I: O3 b- u
  172.         for (i = 0; i < 8; i++)( c' P. q  X  ]# ?( W1 @9 B4 l
  173.         {
    % M: h0 D# S4 W+ L0 G
  174.                 0 t8 C. M" Z' v, H( C/ H
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */+ |% B  f8 v/ z+ p& ^+ r, {
  176.                         SI = 1;" y( y4 r, [' }$ q4 |4 `" C
  177.                 else
    ! S- ]/ g9 }& P3 W$ |/ }) z
  178.                         SI = 0;                                /* if not, set to low */
    , T; e; @7 }' L8 B$ H% T
  179.                 SCK = 1;                                /* toggle clock high */: J- l* [: Z: ?0 c; p
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    $ i: _) q; Y/ w8 W: w( x- P
  181.                 SCK = 0;                                /* toggle clock low */# L% E, Z3 c7 \
  182.         }5 P7 u2 H0 e6 T4 Q- Z4 m1 @" N
  183. }
    ( I$ E: H9 ?5 Y2 q
  184. - a' Y! K+ o* ?/ j1 b/ V* |
  185. /************************************************************************/
    + n0 c) i* g) k
  186. /* PROCEDURE: Get_Byte                                                                                                        *// T+ p2 c) }( `2 J2 H
  187. /*                                                                                                                                                */8 `* I1 _2 O" }) I0 M
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */) ]% K) q- |# ^4 I; P; D
  189. /* edge on the SO pin(LSB 1st).                                                                                        */( b/ J+ ^5 H2 P2 u5 _
  190. /*                                                                                                                                                */
    " w8 Q8 `. q/ g% `
  191. /* Input:                                                                                                                                */. f5 ?: t0 B. B  r4 m
  192. /*                SO                                                                                                                                */. O! y, ?' u* b% F; E. o
  193. /*                                                                                                                                                */8 }( c9 h# S  ~4 a
  194. /* Output:                                                                                                                                */
    ) k% O4 X, m/ F* I1 G9 N/ m. U
  195. /*                None                                                                                                                        */2 ?: {/ Q. p, u' R+ \
  196. /************************************************************************/: }8 `* l4 Q2 X: g5 d2 k! }( Q1 l* x& L
  197. unsigned char Get_Byte()
    9 Y1 p4 v  n3 Z0 g
  198. {
    3 w+ y% f0 Z, I* W
  199.         unsigned char i = 0, in = 0, temp = 0;
    , e  @# q* H" G6 H
  200.         for (i = 0; i < 8; i++)  i7 y6 ^# ]1 l0 l
  201.         {
      e6 q1 t* z( ^6 O
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */! @5 B# c4 n: U' I* }+ W
  203.                 temp = SO;                        /* save input */
    0 j$ c" n* ]( N& z! d
  204.                 SCK = 1;                        /* toggle clock high */: ]; H3 Y3 v0 o; I/ A
  205.                 if (temp == 1)                        /* check to see if bit is high */
    * H& Y# X( l' W: i3 S
  206.                         in = in | 0x01;                /* if high, make bit high */
    2 E1 J# i3 Z) l; z& ~& S

  207. - T/ P: M# J3 |( N/ {1 ]4 |; z
  208.                 SCK = 0;                        /* toggle clock low */% O) x, A7 g! k# h, x" ^% O
  209. 6 a9 o6 w6 Q1 ]0 C* C7 D4 Q
  210.         }2 z% y$ k; R' F) G! M, T2 K
  211.         return in;& y" h5 N! N' E, [* `7 Q- M  s
  212. }3 A1 p$ l8 m/ ]+ v$ a% i( ~
  213.   |) E# }+ T3 L4 C
  214. /************************************************************************/: T" q2 L% x" B5 ]
  215. /* PROCEDURE: Poll_SO                                                                                                        */. w" e9 R1 q) D( `, t/ H
  216. /*                                                                                                                                                */
    , Q! d* E) @% p8 A7 a1 R
  217. /* This procedure polls for the SO line during AAI programming                  */
    . I* N+ x- V. R* F
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    ; I1 q, B1 m6 y
  219. /* is completed                                                                                                                        */- }) v  T) R6 X* F3 A( Y) m$ H
  220. /*                                                                                                                                                */. C4 b- L+ _. q
  221. /* Input:                                                                                                                                */
    3 z# [* E$ e9 D/ d, k
  222. /*                SO                                                                                                                                */
    # ^. N5 J/ F; p. k. v
  223. /*                                                                                                                                                */
      e5 l! Q: ]5 J) U, I  F
  224. /* Output:                                                                                                                                */3 j" S, h6 [7 K% |1 }, J3 D
  225. /*                None                                                                                                                        */
    4 h1 t) Q. M1 Q5 q3 m8 D
  226. /************************************************************************/) C' `* u" |! W( E6 S6 k+ t' I
  227. void Poll_SO()
    ; f! W: t2 p6 I, n5 d0 ^9 f
  228. {/ B3 v2 ~5 N4 p* F2 Y& j
  229.         unsigned char temp = 0;
      G; g& U- J7 R: o3 h; Q& F  c8 `
  230.         CE_Low();
    ! o8 f# q& W& Y  B
  231.     while (temp == 0x00)        /* waste time until not busy */* y, N+ k/ I, j9 H
  232.                 temp = SO;
    * r) v) \0 k, W' |; c
  233.         CE_High();
    / X% v0 M. @# g, h( @2 g1 _
  234. }
    0 A7 b# S: K, U+ D

  235. 2 ^' K; y) p0 C- [; V
  236. /************************************************************************/
    % S3 Q. A  y( O0 R) T; I
  237. /* PROCEDURE: CE_High                                                                                                        */
    % C; t2 W  w& R; k+ W* x4 g
  238. /*                                                                                                                                                */6 _" C, f% r. F; H& O7 ^
  239. /* This procedure set CE = High.                                                                                */
    ! Y, g) ~1 x, [% E
  240. /*                                                                                                                                                */. o; c; B* x. v  Z
  241. /* Input:                                                                                                                                */! P9 j$ R7 s3 S; M
  242. /*                None                                                                                                                        */+ x+ {! r1 i  {5 @) u
  243. /*                                                                                                                                                */
    # M1 u4 f9 ]% o0 R
  244. /* Output:                                                                                                                                */
    # ~( r3 a5 W8 m2 m8 u7 |' i6 x
  245. /*                CE                                                                                                                                */
    + ~  V5 Z. v& h- b/ d
  246. /*                                                                                                                                                */! P' n6 v6 k( \3 a/ m1 f, U" d
  247. /************************************************************************/
    ! _3 g& p2 T. g
  248. void CE_High() 9 h) w9 ~* Z2 u  i) o$ l. |
  249. {
    $ l: M' n2 \  M$ R
  250.         CE = 1;                                /* set CE high */7 \9 p/ M% X5 z# @# F1 h, m
  251. }
    ; b  t  a9 o' s% p- i5 }

  252. % r& h$ b* j* c
  253. /************************************************************************/5 S7 Z; r4 z4 |4 \* r, w% e7 a8 F0 _
  254. /* PROCEDURE: CE_Low                                                                                                        */! s. k$ ^) z) ~$ T  [) W1 b6 ^' d
  255. /*                                                                                                                                                */, x4 A2 e/ a5 l3 ~8 i0 k
  256. /* This procedure drives the CE of the device to low.                                          */
    $ E; R8 b$ q! Q9 L* v9 ^
  257. /*                                                                                                                                                */" R/ F9 J. Z# p% j8 @4 x' b) z$ M9 r
  258. /* Input:                                                                                                                                */
    - V! k" L6 p; \
  259. /*                None                                                                                                                        */
    0 G# x% g( ]  j& B# a) q9 s! \
  260. /*                                                                                                                                                */
    6 S3 t/ Y: k1 W! ?! {$ O
  261. /* Output:                                                                                                                                */
    & q# K) Z8 x9 j/ o
  262. /*                CE                                                                                                                                */
    4 h' C# }( o* y8 t8 H
  263. /*                                                                                                                                                */
    : N+ j6 s4 U; G( x4 x4 D
  264. /************************************************************************/
    6 c7 @8 O4 e- v- _! t/ w
  265. void CE_Low()
    : u$ I! q" Y7 h; r* Z* w9 [, E
  266. {        , q9 V( V, a$ V" M. c' R/ v- s
  267.         CE = 0;                                /* clear CE low */  k2 f: m% Y5 i# f" @! L* i7 m$ k" b
  268. }
    - ?8 m: }/ J( u- |/ A" _2 J, Z
  269. # F; _' [7 r* j$ x  K5 C
  270. /************************************************************************/! k. Y9 o; Y! i, J  r' Z
  271. /* PROCEDURE: Hold()                                                                                                        */: I8 F* ^; i9 t
  272. /*                                                                                                                                                */. v; k7 t. T1 D! ?
  273. /* This procedure clears the Hold pin to low.                                                        */' U) D' C, M& V% e1 m) z5 `1 J
  274. /*                                                                                                                                                */
    * m# @  g5 v5 V
  275. /* Input:                                                                                                                                */
    8 _1 T3 V# T1 K/ V. e
  276. /*                None                                                                                                                        */
    6 R" t; A. C. v
  277. /*                                                                                                                                                */) r: ~8 q1 H7 z9 X
  278. /* Output:                                                                                                                                */
    3 T8 `1 C+ x( }5 u
  279. /*                Hold                                                                                                                        */
    3 S7 c2 I1 a3 G2 t. C9 t
  280. /************************************************************************/
    % N# I. r; H) ^, j
  281. void Hold_Low()
    ; i$ l9 d& _$ ~7 `# ]1 [
  282. {  m. L! |( y6 ]4 n0 a
  283.         Hold = 0;                        /* clear Hold pin */
    ; y- \/ W+ _7 B( c7 ~
  284. }
    ; T" c* c! |$ y' V

  285. 0 a, }) ]7 _0 n4 p1 T) H/ ~% b3 g
  286. /************************************************************************/2 N* `# `9 H) P! D  n
  287. /* PROCEDURE: Unhold()                                                                                                        */
    3 g+ F/ L2 M! T& L+ K- T
  288. /*                                                                                                                                                */
    # E) d7 R* `( ~1 h; J
  289. /* This procedure sets the Hold pin to high.                                                        *// p, d. ?; j$ L+ L1 b# L4 W1 _
  290. /*                                                                                                                                                */: h- F/ x) d  D4 `5 P/ t; b
  291. /* Input:                                                                                                                                */( z( f  ^' Y( g2 A5 ~
  292. /*                None                                                                                                                        */% s( a2 m# ^0 T* y
  293. /*                                                                                                                                                */
    % ^+ E1 P. Z. f  x2 i
  294. /* Output:                                                                                                                                *// E$ r7 F- M' t+ n! h( M
  295. /*                Hold                                                                                                                        */
    # [) l2 }* \+ |9 u; [- X
  296. /************************************************************************/
    # B. `8 b6 x& B  [( [8 h4 P# Q
  297. void Unhold()
    / F2 B0 `! G& @: `7 W! L1 Y! f
  298. {
    : d% N8 B1 r, u* b6 S
  299.         Hold = 1;                        /* set Hold pin */# \8 _) ?) Q2 V, i. u$ S
  300. }7 U  Y. q! M$ Q6 C9 b# J+ x, g2 e

  301. $ l3 m2 \' L2 ~, c1 R1 K
  302. /************************************************************************/
      \3 M" j2 L; D6 U/ ?% q
  303. /* PROCEDURE: WP()                                                                                                                */1 N$ B1 ]  j9 o0 W5 y3 ^$ _2 M
  304. /*                                                                                                                                                */
    # Z" y3 x! |0 I% y$ f# U: l, D
  305. /* This procedure clears the WP pin to low.                                                                */
    * d/ z) ]4 u7 L  X% T4 X
  306. /*                                                                                                                                                */  C" T6 N- D& o- g4 V4 r
  307. /* Input:                                                                                                                                */
    + {& f/ E- D! @
  308. /*                None                                                                                                                        */
    3 D0 J1 m% f2 K. h7 t
  309. /*                                                                                                                                                */5 @" |+ c" o$ N  R5 b$ r
  310. /* Output:                                                                                                                                */. W( d3 s6 c' s) W0 n. W7 F4 v
  311. /*                WP                                                                                                                                */3 g; B7 b) h* `$ K! b2 O2 ~1 A
  312. /************************************************************************/6 G. g( s/ `: L/ y& q
  313. void WP_Low()3 ^; r7 X* U  T4 g
  314. {% r/ D) J  r- N, b4 c3 z$ \- K0 q
  315.         WP = 0;                                /* clear WP pin */
    4 W; l" o5 C  o; g: s/ n7 z
  316. }
    , I2 N: q$ b1 u3 M

  317. ) H, T" `9 ]4 Z% r% F9 R% N
  318. /************************************************************************/
      T% e6 j0 D8 g- `, K, N0 ~* ~0 r  B
  319. /* PROCEDURE: UnWP()                                                                                                        */
    , `) Q; O( o# b8 b6 U4 ?
  320. /*                                                                                                                                                */
    ! S$ n* R" s- S3 C
  321. /* This procedure sets the WP pin to high.                                                                */
    - A: R$ H5 \) ?/ f1 D
  322. /*                                                                                                                                                */
    , a, Z* c- @+ V2 c
  323. /* Input:                                                                                                                                */
    1 \. C, }8 `: T( A
  324. /*                None                                                                                                                        */
    $ G4 x6 e& n7 w. y6 [/ f0 t* B7 R
  325. /*                                                                                                                                                */, {, _% l, Y& v7 r# Q5 G$ A- b1 @
  326. /* Output:                                                                                                                                */+ Y3 x  R$ v9 Q& X7 w( m# b& B
  327. /*                WP                                                                                                                                */. j* \* j! Z- t$ V7 Z) u) F0 s+ }
  328. /************************************************************************/* e& c" ~0 G" b9 i6 O0 O
  329. void UnWP()
    - t+ i3 ^6 y5 S( k% w6 C& y
  330. {
    / X2 ^% R: ?4 Y1 {6 E
  331.         WP = 1;                                /* set WP pin */
    % S0 ]7 p) }2 H' G$ _+ D* ?
  332. }  K3 H  Q. P# z
  333. ! p* K7 C0 {& Q! Y, s( r
  334. /************************************************************************/; u6 }2 O- e9 K3 k1 l  X2 ~3 F! U
  335. /* PROCEDURE: Read_Status_Register                                                                                */+ o8 e% n7 c' v) I7 U  m% L! }/ u! z! S
  336. /*                                                                                                                                                */. U( o- _  E  {0 v7 }3 H! L8 c
  337. /* This procedure read the status register and returns the byte.                */
    7 ~0 `' B# @% b0 ^
  338. /*                                                                                                                                                */
    - i+ g3 W2 }  W
  339. /* Input:                                                                                                                                */
    3 v5 m8 J# r# H" \5 T8 X& p! D
  340. /*                None                                                                                                                        */+ K+ h" `" z& Q
  341. /*                                                                                                                                                */
    , n; ^9 i. N9 i1 I9 D
  342. /* Returns:                                                                                                                                */
    % M) b0 L5 H. P, u) @
  343. /*                byte                                                                                                                        */7 x3 e5 J/ X2 s) f
  344. /************************************************************************/4 E. z9 x4 ^) N- R5 V
  345. unsigned char Read_Status_Register()  e+ ]4 f8 h# J8 Y
  346. {3 e# m8 Z# U% O' D1 |0 q  H
  347.         unsigned char byte = 0;! M/ A1 D4 W- m+ a) F- o( V% s" |% c
  348.         CE_Low();                                /* enable device */! I3 `( Z4 U2 f4 z/ b, k- T, b) U
  349.         Send_Byte(0x05);                /* send RDSR command */! V, e" f# a( N. }, ^
  350.         byte = Get_Byte();                /* receive byte */8 t) n5 ]# _2 i, u+ G) Z6 L
  351.         CE_High();                                /* disable device */
    + f( r& @% a7 p5 {+ {# h
  352.         return byte;" i8 Z8 H# ~$ J( _; `0 Y0 R
  353. }/ d* c1 L/ s$ j& k1 [  W
  354. 3 j1 _" r  x# L7 n. x0 w2 S8 @# y
  355. /************************************************************************/
    ! c+ k: A/ Q7 y) E
  356. /* PROCEDURE: EWSR                                                                                                                */
    : k: k' s3 l6 w" F& A
  357. /*                                                                                                                                                */  B7 O% L* N3 Z. L. c! U
  358. /* This procedure Enables Write Status Register.                                                  */
    4 k/ c! \. i3 j1 j1 {
  359. /*                                                                                                                                                */+ a& L; b, p8 q& _- @0 J
  360. /* Input:                                                                                                                                */
    8 ~! H. B8 i. C2 V/ N2 Z
  361. /*                None                                                                                                                        */4 w4 l; J3 o/ t; A
  362. /*                                                                                                                                                */
    ) T2 n0 t! O+ o
  363. /* Returns:                                                                                                                                */: Z* ]9 I  B) }. `. i; t) C
  364. /*                Nothing                                                                                                                        */
    4 m) l( a7 M8 S# V' t% e
  365. /************************************************************************/
      i" M% K. J9 ?. A2 w- p! t
  366. void EWSR()
    ; B# O; q6 ~" y% r; n# D8 ]2 ~
  367. {
    3 ^7 m! F5 t0 d& u/ ~% K; T8 d
  368.         CE_Low();                                /* enable device */
    8 p" R' n% i1 ], N; u, R5 m- \( _3 u
  369.         Send_Byte(0x50);                /* enable writing to the status register */6 |) b3 z! j7 ?: J
  370.         CE_High();                                /* disable device */' X2 P5 F: ^- c( z" H/ I
  371. }$ G' M( Q9 O7 z$ [: t$ O- S
  372. 2 P/ J' V( ?; \0 y
  373. /************************************************************************/
    1 a) ~7 l7 z; b
  374. /* PROCEDURE: WRSR                                                                                                                */
    $ L% K3 w5 {. ^" ?
  375. /*                                                                                                                                                */
    ; d8 p0 N" y* o% G
  376. /* This procedure writes a byte to the Status Register.                                        */+ `) b. _2 b" l  q" V, H' M5 h
  377. /*                                                                                                                                                */  a: @9 V, t: }' V+ D$ f
  378. /* Input:                                                                                                                                */, T9 R# P- M" m. f- J
  379. /*                byte                                                                                                                        */
    9 i" G  \4 `( A$ x4 c
  380. /*                                                                                                                                                */
    , }! f7 ~- I2 j
  381. /* Returns:                                                                                                                                */
    : e2 ^7 t6 w5 B
  382. /*                Nothing                                                                                                                        */& Q: z% r6 c6 U% ^# X+ u* S) j+ ^
  383. /************************************************************************/
    ( i. m- y; \7 W
  384. void WRSR(byte)& U$ F( E" D  f9 Y) n
  385. {
    6 r- V. B  z1 ~& P3 j
  386.         CE_Low();                                /* enable device */
    - G" A- }$ B6 u# H
  387.         Send_Byte(0x01);                /* select write to status register */0 I' e3 o: M/ ], a" q; h
  388.         Send_Byte(byte);                /* data that will change the status of BPx & O+ h  A, v. s7 W2 |8 L1 h% K
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */) Q7 g% [! c9 M1 O3 B
  390.         CE_High();                                /* disable the device */0 i! N: X5 c5 p/ e* I5 m5 H: t
  391. }, A; B6 n- N" g3 j
  392. % K9 m4 Q2 ^  f: k2 D: g
  393. /************************************************************************/; e& \2 i$ ]4 Q. o& P! u
  394. /* PROCEDURE: WREN                                                                                                                */
    " L  R7 J* x; J& R: P
  395. /*                                                                                                                                                */3 P& E5 u* ^$ I
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    1 t6 V. b/ X8 a
  397. /* to Enables Write Status Register.                                                                        */
    " x# k/ }1 r5 y2 Z9 `
  398. /*                                                                                                                                                */
    # @0 o# f" ~. E7 ~' A$ f
  399. /* Input:                                                                                                                                */
    / E" y( P/ Y3 l
  400. /*                None                                                                                                                        */: y& {! i" u, d- e7 @" z
  401. /*                                                                                                                                                */' X$ D! w' @& J8 P
  402. /* Returns:                                                                                                                                */( s/ Z" N, x  W
  403. /*                Nothing                                                                                                                        */6 ]2 w/ h+ a' `- E; ]
  404. /************************************************************************/
    / M; f. c0 p: z- s
  405. void WREN()" d6 \) c8 q1 q* s% i' N( p2 j
  406. {( x) E0 p  l6 u8 O' I& i
  407.         CE_Low();                                /* enable device */# [% h" [- o" U) q1 S! c
  408.         Send_Byte(0x06);                /* send WREN command */5 ]" n6 o0 J1 G" D$ v! M6 J6 d; A# X
  409.         CE_High();                                /* disable device */
    ' b/ ]9 @/ ~. i/ q: K& ^4 C8 X6 i6 ?
  410. }
    7 J8 r& I" H( [# B

  411. 9 A& v9 K+ G5 }3 {9 c$ F" S/ O
  412. /************************************************************************/
    % Q; W$ ]$ l1 d# v
  413. /* PROCEDURE: WRDI                                                                                                                */, y& i6 n' C5 [! O
  414. /*                                                                                                                                                */
    $ k6 Y, P$ {# w
  415. /* This procedure disables the Write Enable Latch.                                                */+ G( D/ b* E7 r; V0 j, q& n/ E
  416. /*                                                                                                                                                */* x5 s+ j# {0 a1 X5 \' v
  417. /* Input:                                                                                                                                */$ Q* j" _+ R& r" ~
  418. /*                None                                                                                                                        */5 D) ]* ^& O' `4 e
  419. /*                                                                                                                                                *// E, }4 c9 N5 Z5 I" ]8 b6 |3 h
  420. /* Returns:                                                                                                                                */
    ) N' [5 [' p$ g  f
  421. /*                Nothing                                                                                                                        */
    7 s1 R; U$ ^# f. c
  422. /************************************************************************/
    . |3 N/ q( G4 O3 r6 G% T
  423. void WRDI()  Q; L. r5 ?" n" w3 y
  424. {+ u' P, z# }2 i7 w  i
  425.         CE_Low();                                /* enable device */0 Q- I2 Y  `9 C; e  K  s
  426.         Send_Byte(0x04);                /* send WRDI command */# J$ n+ T7 L. x& o" z
  427.         CE_High();                                /* disable device */+ }  g$ f% n: h" G% S2 |
  428. }
      N, H1 T' ^8 [$ ]  g' }4 a

  429. 4 K3 A3 d: l( Z
  430. /************************************************************************/
    2 ]2 y) r9 I! T2 ~& j0 o" T
  431. /* PROCEDURE: EBSY                                                                                                                */
    ' Z) I' I$ f6 ^6 K3 i4 C: l9 P& `4 a
  432. /*                                                                                                                                                */
    9 X1 Q" ?3 ~3 I! B3 A
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    ' X. W0 ^4 s8 R/ P9 L
  434. /* programming.                                                                                                                        */) v2 _, j+ m4 G6 A9 b. I" R" E
  435. /*                                                                                                                                                */8 X3 y* H8 t( n& {  r: k1 ?+ D/ ]
  436. /* Input:                                                                                                                                */1 a' K- F. \9 v! @0 k/ Z
  437. /*                None                                                                                                                        */& r8 B; q. [  i$ X: [" J( Y' q
  438. /*                                                                                                                                                */
    / M* N# }; X/ \3 i
  439. /* Returns:                                                                                                                                */1 @# S8 q% g2 O4 _5 f
  440. /*                Nothing                                                                                                                        */, k, o% P$ u$ J
  441. /************************************************************************/0 J2 y9 e9 m* f- q$ E9 W
  442. void EBSY()
    ( s$ @4 z2 I7 L1 T$ ]: G
  443. {
    4 w. a: [! A' Z  t
  444.         CE_Low();                                /* enable device */& X5 M, ]- Z4 x$ e
  445.         Send_Byte(0x70);                /* send EBSY command */
    " _# ?+ Z: S) o# `+ G/ t
  446.         CE_High();                                /* disable device */+ U4 b) U- q9 `( T+ [. Z& ?
  447. }+ u: ~% j. a. p
  448. 9 |# F' x) L6 v+ d2 t8 F$ ~
  449. /************************************************************************/
    , K* }9 I7 u# i- }
  450. /* PROCEDURE: DBSY                                                                                                                */
    # r- [& U$ X( x
  451. /*                                                                                                                                                */
    + `, O& b- z. E: L3 }4 h" v
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    , ]; ~. L% e1 C5 O+ H: Q( j6 u2 T
  453. /* programming.                                                                                                                        */
    . H: B2 z4 C* n% q( s
  454. /*                                                                                                                                                */; D6 _) U2 Z* t7 C( E8 Y1 j" W% ]2 E
  455. /* Input:                                                                                                                                */
    * j! H1 r8 |- y+ N2 n0 D
  456. /*                None                                                                                                                        */
    9 f  ]! B9 Y  O4 V
  457. /*                                                                                                                                                */) V% Z7 r9 N( i8 H$ o) K. K- B% O& C: m
  458. /* Returns:                                                                                                                                */( ?" u- G  C) W: z; V4 |4 I0 S
  459. /*                Nothing                                                                                                                        */
    3 Z/ ~3 v" K" ?5 B) n7 V
  460. /************************************************************************/
    & a" z7 W. ~" L4 {1 m% m0 L
  461. void DBSY()
    6 a. c0 f2 u& `* h7 f( I/ k
  462. {
    " M6 T, w; a9 }1 d& X) W' X' J
  463.         CE_Low();                                /* enable device */
    / t+ L& O( y$ R. ]# n9 v+ S, Z
  464.         Send_Byte(0x80);                /* send DBSY command */
      C6 C, d& l  c. y
  465.         CE_High();                                /* disable device */
    5 Z1 @6 o" u. n) x
  466. }
    ; M6 ~5 |+ p9 n+ v5 X/ z5 Q

  467. 7 B7 X4 J1 {9 q7 e3 W/ i
  468. /************************************************************************/) S9 ?9 j, b* S5 P* `
  469. /* PROCEDURE: Read_ID                                                                                                        */9 ?+ b0 ?! N6 h* I) B# {9 I
  470. /*                                                                                                                                                */% w6 a8 z* \# A- Z1 F6 p- g) M
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    6 @/ O- C0 s8 V, r7 Q
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    - L" p$ C( [7 [4 W$ Z
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    ! ^+ V+ K; j; t7 _  e
  474. /* whether the device outputs manufacturer's ID first, or device ID         */" f  I3 d$ Q6 B; Q4 p
  475. /* first.  Please see the product datasheet for details.  Returns ID in */( o4 r0 z  h# v1 o
  476. /* variable byte.                                                                                                                */
    & a8 k# e5 R  @* M7 A% }6 p9 _2 B3 ~* J1 `
  477. /*                                                                                                                                                */
    8 ]7 o) z$ G5 r7 k0 a
  478. /* Input:                                                                                                                                */
    - q! {# B& |- Y, [1 R+ |4 \
  479. /*                ID_addr                                                                                                                        */3 S5 }! R4 Y! I7 r* v" u
  480. /*                                                                                                                                                */' g' |- j. l( p3 l: q
  481. /* Returns:                                                                                                                                */9 b! o" L) U1 @7 _& B$ ]! R& D
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */9 _& F6 }% n5 s& `
  483. /*                                                                                                                                                */
    & p$ ^7 N' q* y* N& Y
  484. /************************************************************************/
    + ?) ?9 ], ?0 A5 r4 @) Z
  485. unsigned char Read_ID(ID_addr)
    " o  V. C2 i0 l. P, A, o, ~( B
  486. {
    0 z& C9 `3 i. v% o( D" ^& W, I
  487.         unsigned char byte;. ^( @- a; W" s* a. r% R
  488.         CE_Low();                                /* enable device */' G5 s7 S( i# ~2 h4 R* Z2 {0 Y
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */0 w( t; [7 l& D& ~
  490.     Send_Byte(0x00);                /* send address */% O' ]# u* j1 h+ E1 n
  491.         Send_Byte(0x00);                /* send address */
    . |/ P5 J% c. r2 g9 J
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */' @+ u- R' J' p+ w5 E
  493.         byte = Get_Byte();                /* receive byte */
    1 m7 `) @5 X; ?+ R9 {2 o
  494.         CE_High();                                /* disable device */
    0 W# m% k  S7 T- `
  495.         return byte;
    # T  u2 E( E( H6 h, o; ?
  496. }
    1 G6 P& w# d( J6 G3 e& X
  497. 8 h, A$ a  R$ B6 I
  498. /************************************************************************// Q( Y: w) w% l8 [4 }) z
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    5 _' U2 a+ z$ q
  500. /*                                                                                                                                                */
    5 r) t4 i/ r: ]4 }. O$ W2 S
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    * E3 d) `- W8 k5 d. b6 q0 Y; k
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */8 h; I3 `$ C9 C; ^0 i
  503. /* Please see the product datasheet for details.                                                  */" A# k) {% x9 q# P9 N' e9 z
  504. /*                                                                                                                                                */. \& Y+ V8 R% q9 {2 D& \4 _
  505. /* Input:                                                                                                                                */
    & u5 @7 m: v, S( Z$ J: m/ _  l
  506. /*                None                                                                                                                        */
    + T: L+ y0 X3 r
  507. /*                                                                                                                                                */7 A% k# b: J+ B9 f
  508. /* Returns:                                                                                                                                */
    ! k; C; x7 V4 |* ?
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    / F$ Z% o' L/ I. J
  510. /*                 and Device ID (8Eh)                                                                                        */7 [" S2 f* [7 a; {
  511. /*                                                                                                                                                */
    0 U. Z. a/ a: b' G
  512. /************************************************************************/( W4 g- l; m& N# I
  513. unsigned long Jedec_ID_Read() 9 F' i9 E7 {( L, y% N
  514. {2 S4 E* V7 G# s
  515.         unsigned long temp;
    7 C# b5 }1 |, m8 G9 i8 I5 }8 s
  516.         6 l. s2 G9 U2 j2 q. S. S
  517.         temp = 0;; l8 J+ P  _& @: Z8 F' O

  518. 9 C6 \& p4 ?/ A! a* S
  519.         CE_Low();                                        /* enable device */
    + r( W. G4 [  I; j2 A. S8 S2 ~
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */2 u5 s1 D% [/ V0 c
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    6 p/ a2 Y$ _, O2 }  j0 f0 S
  522.         temp = (temp | Get_Byte()) << 8;       
    ; d  |$ Z5 Y/ d1 F  P# @
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    " i# q8 n# L" s+ L/ R. I, Y
  524.         CE_High();                                                        /* disable device */
    : a6 }/ Z+ z8 k1 d9 y* R
  525. " d$ K# u# T, u5 o& s- g+ ~
  526.         return temp;
    + O% `0 u0 ^0 X- v1 q4 n
  527. }9 q3 S- ~: b. l* O, S
  528. " j( ?0 W4 p! w
  529. /************************************************************************/! z/ n6 ^3 N, v( U+ v
  530. /* PROCEDURE:        Read                                                                                                        */" x% m0 R* l# \7 {9 z* G+ R
  531. /*                                                                                                                                                */               
    $ |) E  S8 w7 n
  532. /* This procedure reads one address of the device.  It will return the         */
    ! O3 z4 K8 P$ j2 o
  533. /* byte read in variable byte.                                                                                        */6 [& @% u+ Q- Z) m6 f' j
  534. /*                                                                                                                                                */
    6 S, z7 C7 U# C; G' d
  535. /*                                                                                                                                                */
    5 @+ b$ L$ t. v! y+ G1 I0 r. L, w8 J
  536. /*                                                                                                                                                */, b: r( S% v; ?
  537. /* Input:                                                                                                                                */  S* y6 n% Y; _
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    3 J( N7 L) `( K$ B9 t
  539. /*                                                                                                                                      */0 R, D2 F/ A, b6 ^! Q/ Z
  540. /*                                                                                                                                                */
    4 a2 p: Y* n7 G+ K
  541. /* Returns:                                                                                                                                */, k& b2 D6 R5 k7 B( B* ?
  542. /*                byte                                                                                                                        */; T' c  J1 I. m2 k. `
  543. /*                                                                                                                                                */2 D0 A8 f0 B. l, |
  544. /************************************************************************/
    3 A: X7 w% p: c& T# q9 }2 ^% y
  545. unsigned char Read(unsigned long Dst) % b) ^: {8 p! m( b* g( h
  546. {% N9 Y6 y& C) @6 S
  547.         unsigned char byte = 0;       
    * d( k3 r4 I- ~
  548. # x9 N0 I/ {6 x9 b! G, u/ X5 d  R# h
  549.         CE_Low();                                /* enable device */
    / M8 q& F. y$ e! ?# ]! D2 q6 O
  550.         Send_Byte(0x03);                 /* read command */
    # s# ]! j' d: ?! q. L
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */- L) d8 \: o, i. w2 L
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    0 y6 y$ I6 v9 s7 i+ k6 C" D
  553.         Send_Byte(Dst & 0xFF);5 i7 q( _/ H+ \' B( C% F( k; a8 `/ ^
  554.         byte = Get_Byte();
    / n2 \0 S! i% n+ m2 E6 y
  555.         CE_High();                                /* disable device */$ k( _" B# |& n- h5 o
  556.         return byte;                        /* return one byte read */6 _; ~2 t4 z# L2 s3 c
  557. }
    " M! P6 N6 q* z) o  d% G

  558. - u$ g6 J! J5 j- i
  559. /************************************************************************/
    . d% n- c& d1 C
  560. /* PROCEDURE:        Read_Cont                                                                                                */) }% [8 O$ g+ G
  561. /*                                                                                                                                                */               
    . c; ]# Q# y4 D: M
  562. /* This procedure reads multiple addresses of the device and stores                */) {! I5 `* n8 M8 a
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/" d, {3 W$ `4 b0 X! j2 c3 c* i4 D
  564. /*                                                                                                                                                */
    6 C" e/ f- F0 M* ]$ g
  565. /* Input:                                                                                                                                */+ ?& c" _( H: N
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */9 L+ u5 g1 _. i, G$ V, M  U/ D
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */) e7 _) @% x, `  u
  568. /*                                                                                                                                                */4 i/ y6 n; N! ?0 n; H1 m, ~, A
  569. /* Returns:                                                                                                                                */* g; S6 f$ i! v  e, ~
  570. /*                Nothing                                                                                                                        */) I0 @  e" }$ C/ l% n; v
  571. /*                                                                                                                                                */
    $ j/ k' I: z; j" ?3 v3 u! c  v
  572. /************************************************************************/
    4 _$ A4 b" u/ ]) M' W$ h
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)" C, [' j2 I6 u8 V8 @
  574. {
    $ u* m  g( q- o" @, |' S
  575.         unsigned long i = 0;  K& Y" q* I3 ]4 [: a# T) I' _2 B, z
  576.         CE_Low();                                        /* enable device */
    0 Z; |. A! |5 A# G7 L
  577.         Send_Byte(0x03);                         /* read command */
    8 ^8 l, w$ U* C4 w/ U9 O
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    $ d8 Z' G4 U4 \
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));6 S4 U2 [) i+ w
  580.         Send_Byte(Dst & 0xFF);
    * t" L, ?9 l  T: b2 C
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    & f- y2 a8 w* K
  582.         {
    ( Q; z$ F" M- G- ^. \' `! z
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */) q1 m; _& p) G
  584.         }
    / Q6 @& Q6 x* [, p# Y4 J% B: f) c
  585.         CE_High();                                        /* disable device */
    ' |* t6 S; @  O7 V

  586. , z$ ~5 H0 K$ G4 }) X* L( U
  587. }9 N! B: l# ~* C) V7 T# Q
  588. " C$ u% I: w& c7 N. v
  589. /************************************************************************/; C1 \. v! W, F
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */8 Y. h3 n* c, `8 P  m/ g% I5 _! _
  591. /*                                                                                                                                                */                * i% e6 S& z  d
  592. /* This procedure reads one address of the device.  It will return the         */9 h( d  o2 L1 Q( |6 F4 t+ H( x
  593. /* byte read in variable byte.                                                                                        */1 T0 a& v, n" P+ i! k+ v  g$ ^
  594. /*                                                                                                                                                */9 |: X# m4 Z. j0 b
  595. /*                                                                                                                                                */$ @) \) u) H# {: m. F  C; T$ A& @
  596. /*                                                                                                                                                */
    3 I. B) y$ A0 M( |9 I
  597. /* Input:                                                                                                                                */; y, C7 q6 O, n8 U8 ]
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */6 Y$ L6 @" Y1 g9 v- f6 i1 e
  599. /*                                                                                                                                      */1 |0 Z! n& d/ F% r% g
  600. /*                                                                                                                                                */; N4 c( y( S$ |
  601. /* Returns:                                                                                                                                */  A; n) U( @& O( }) Q
  602. /*                byte                                                                                                                        */3 Y' q" ~# `0 K8 K& {
  603. /*                                                                                                                                                *// ?/ ^# g8 o" @& w3 {+ C
  604. /************************************************************************/
    / U3 j$ D1 ?8 D: `9 M2 e2 }- e3 t
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    8 w, B0 B5 A$ r1 ^8 O
  606. {3 m- g1 y, |- s+ W
  607.         unsigned char byte = 0;        ( ~+ z( S3 E5 K8 v

  608. : ]3 _3 z4 z9 d5 A$ K
  609.         CE_Low();                                /* enable device */
    ' b5 X9 I0 n- c8 y& ~" u, D
  610.         Send_Byte(0x0B);                 /* read command */: H$ a$ \' T+ o  d" N* r
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ! R: a# r2 H0 T, D! v0 g" e( K1 b, C7 O/ T
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));! b0 t+ \. Q; V! W# Y7 E
  613.         Send_Byte(Dst & 0xFF);# r& Z- U- K; `" H
  614.         Send_Byte(0xFF);                /*dummy byte*/
    9 c+ _& e. P4 ^- h
  615.         byte = Get_Byte();, h& i2 q2 a( n* E: L- G0 j
  616.         CE_High();                                /* disable device */, v  t6 _% H; b1 r8 I
  617.         return byte;                        /* return one byte read */8 }/ j. ^7 B5 \: ^/ l1 D
  618. }
    0 L& Y$ G8 P" v% u0 f) Q

  619. # Y0 ?$ H) ~! r; a0 V- ~& l
  620. /************************************************************************/
    : m4 h2 i" z5 f$ Z6 }
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */+ M8 x8 j# ?* R. ^/ x1 f
  622. /*                                                                                                                                                */                & J! c! ]& L9 w0 ?6 D" Z% @
  623. /* This procedure reads multiple addresses of the device and stores                */, _+ X; N, t9 ~& B1 R; {. V. c4 z
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/  S. X) _  U; ], L- `: @/ }3 ]
  625. /*                                                                                                                                                */
    ' I! {5 x/ S1 f, z
  626. /* Input:                                                                                                                                */
    ) z0 O& M" B7 u+ [; \7 t
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    9 C6 x# |/ p" |% c
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */8 F( h- K- c* z" ^2 h; M
  629. /*                                                                                                                                                */" a2 S# a- I9 }$ S: Y, X
  630. /* Returns:                                                                                                                                */
    1 m8 q7 R- w5 J, ]
  631. /*                Nothing                                                                                                                        */
    " Y4 ~7 P* E* Y4 z# `7 X
  632. /*                                                                                                                                                */
    . z) t) I7 t+ H2 v6 m5 Y
  633. /************************************************************************/3 \# P! [; D7 i
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    2 J3 L8 [8 }0 o
  635. {
    5 @$ L! z( q5 G4 c7 b4 P
  636.         unsigned long i = 0;
    ) D5 u  a5 ?: n6 l' f( Y
  637.         CE_Low();                                        /* enable device */
    0 X( l' ~4 p9 K$ H+ ]( X: X* x" X
  638.         Send_Byte(0x0B);                         /* read command */% v4 o0 s( Z; C, l
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    1 o' j1 O# |, h. l' x7 ]
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));! w% O. _7 [4 `4 ]* c
  641.         Send_Byte(Dst & 0xFF);% b/ K! m+ D  J
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    . q4 _( A; s% n$ Z! }# X
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    ; Z/ M$ P4 p. p; F) c5 L' H/ L
  644.         {4 W. d- ~* v# h6 k. u7 \
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH *// L1 s2 I  w, _; Q7 u
  646.         }! d1 }2 \; ?! |& r
  647.         CE_High();                                /* disable device */" i- I$ y2 q  F) [/ I7 X- s/ W: O4 Y
  648. }
    1 v+ k$ M- N" l8 _, J5 d. y1 ~% F
  649. 1 }; r( H! W6 n& F4 E  @
  650. /************************************************************************/* J' _2 A' W/ Q; [
  651. /* PROCEDURE:        Byte_Program                                                                                        */1 X5 k( ]4 R. d% ^
  652. /*                                                                                                                                                */' g* M- x9 S0 X  r% p7 [
  653. /* This procedure programs one address of the device.                                        */, E: A/ l1 a" {, S' F) f' I6 Y
  654. /* Assumption:  Address being programmed is already erased and is NOT        */- X! g% e- P% y. `. e
  655. /* block protected.                                                                                                                */% w- Z# f; {0 J3 ~
  656. /*                                                                                                                                                */: H- w9 @! Y$ o6 P, r; E4 r9 ^4 V6 @
  657. /*                                                                                                                                                */
    ) O% E' ?# s- W$ X
  658. /*                                                                                                                                                */
    ! [  Y3 F* R+ d+ F7 i  V
  659. /* Input:                                                                                                                                */
    " R4 {# c  z, R
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    * K1 d  f# K8 U) ?/ C
  661. /*                byte:                byte to be programmed                                                                */
    ' {  P$ P, r* ]8 c
  662. /*                                                                                                                                      */
    , v0 ~' ^* _! Z  x; x
  663. /*                                                                                                                                                */
    3 L- ?* j1 G4 b6 J" N% g8 }
  664. /* Returns:                                                                                                                                */. C0 z9 E% W* I' t0 N9 e- J
  665. /*                Nothing                                                                                                                        */
    , m" {& N/ e$ e  x. @# p" ?
  666. /*                                                                                                                                                */
    4 J- B2 x# G" U6 s, W1 }
  667. /************************************************************************/1 A4 b4 w# X* ^$ z! C+ f5 x2 K, C
  668. void Byte_Program(unsigned long Dst, unsigned char byte)# ?3 Y4 O9 _' [" Y$ X& S3 M
  669. {2 }- a! ~0 L* ?0 _, O& Y
  670.         CE_Low();                                        /* enable device */
    2 X: h0 F, P- H: X
  671.         Send_Byte(0x02);                         /* send Byte Program command */$ E3 u* A/ m8 D+ g4 P
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    1 P3 ?2 J& x( N/ W; g
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));/ I* s/ P- Z# J* y4 z
  674.         Send_Byte(Dst & 0xFF);6 ?* Z0 R; o( c9 T5 y  j
  675.         Send_Byte(byte);                        /* send byte to be programmed */2 w( n3 e: B  J' s- M! M
  676.         CE_High();                                        /* disable device */+ L; O# M# c7 m* I! o
  677. }2 @4 J# |; J) x/ {( x& h

  678. & Y! ^9 f# }0 ?
  679. /************************************************************************/
      P* ~) g" |5 ]" y3 C
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    8 A. F1 h$ A' _$ ~+ m7 m# Z
  681. /*                                                                                                                                                */
    , ^# S1 g# R) O. U# g: j
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    ) ~+ t* ^- {: Q: h7 E: u
  683. /* the device:  1st data byte will be programmed into the initial                 */, L  S0 m' u4 P2 O
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */8 o- a0 N6 P4 F. m& y2 i
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */$ r/ s* `1 Z( r; J9 A6 n  \
  686. /* is used to to start the AAI process.  It should be followed by                 */
    , \! \/ p# p  d  Q# s2 Y( {
  687. /* Auto_Add_IncB.                                                                                                                */
    / e4 H  U4 C( B
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    8 }) J2 \$ ^5 O4 f
  689. /*                                block protected.                                                                                */" Q; ^( c3 |  S3 B
  690. /*                                                                                                                                                */7 f! \  A. {- E. H+ L- B
  691. /*                                                                                                                                                */
    $ S+ b! U" D+ X. L1 P  I
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    , ]0 f) m5 ^+ j
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */' s0 O+ @4 R- x7 N2 u5 \
  694. /*         unless AAI is programming the last address or last address of                */1 t0 [4 ~4 b- g& r
  695. /*          unprotected block, which automatically exits AAI mode.                                */5 I! S; M5 I1 E2 X& [
  696. /*                                                                                                                                                */% q6 C9 B/ B1 D! o( z  p/ a
  697. /* Input:                                                                                                                                */
    ) k  l' C$ ?# T3 `( J0 u! V
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */" ], a$ Q* ]6 t% _
  699. /*                byte1:                1st byte to be programmed                                                        */4 q5 G" B7 l5 x  W# N6 z; ?& ?/ v
  700. /*      byte1:                2nd byte to be programmed                                                        */2 z' R) V# U- h$ o7 H
  701. /*                                                                                                                                                */
    / C  b, c9 ?) \# g% J4 a" d. w
  702. /* Returns:                                                                                                                                */& T3 q1 m7 W3 c# U! x
  703. /*                Nothing                                                                                                                        */# o# v' q3 S) Y. v$ J) b) ]
  704. /*                                                                                                                                                */( c0 i8 r$ F) C1 \
  705. /************************************************************************/$ y& u6 N! ?5 c0 L' H: k
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)/ O* i( r: v" G( q; _, [; l$ @
  707. {
    ; n; O+ L: \& O7 {
  708.         CE_Low();                                        /* enable device */
    ; m# ?! \7 R4 S# s$ a4 t
  709.         Send_Byte(0xAD);                        /* send AAI command */
      I0 O. ~/ q* N7 |* l
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ( y1 |; h9 ^. K( l5 n4 G
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    5 H5 a3 Z. h; f+ ?7 M5 b/ M/ N; S! w
  712.         Send_Byte(Dst & 0xFF);6 I2 o' r8 g2 E& `! m6 x' K8 g
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    9 h, m7 W5 m& d7 d/ f9 x( I3 y
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
      ]& ~! w- C! {6 U2 _
  715.         CE_High();                                        /* disable device */9 V2 R# C0 k; i' u
  716. }% S) M% W7 k7 j: ~1 m
  717. 5 G3 m) D7 m8 T9 w0 R4 B/ }
  718. /************************************************************************/
    # T& x9 o  a. J* p  \+ M
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    0 }% r1 i; X5 O4 z/ i0 M6 b# G  d
  720. /*                                                                                                                                                */7 f- D3 ]+ m5 K+ h$ x
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/, R1 J1 }) x+ @
  722. /* the device:  1st data byte will be programmed into the initial                 */+ j6 W. V' i& O- k! [
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */; }, g3 q- A3 N
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    8 u  X0 N; u" D6 U, B
  725. /* is used after Auto_Address_IncA.                                                                                */6 b! C5 D! z  o7 U# [3 g) l
  726. /* Assumption:  Address being programmed is already erased and is NOT        */: f& V1 {$ G, Q* c
  727. /*                                block protected.                                                                                */
    $ X+ v, F4 L: V. Y
  728. /*                                                                                                                                                */. B) w) K8 T5 G2 d
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */0 |0 E* Z/ Z8 M4 x; j4 r) Q- O1 G* C
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    / X2 \; [8 v8 N
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ) R" v0 Q: c/ h* ~$ B+ ^! F
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
      P3 J. `* k4 P8 e6 E$ A
  733. /*         last address of unprotected block, which automatically exits                 */
    ) O' @4 h8 c6 h* z8 x
  734. /*         AAI mode.                                                                                                                        */& H) [( {, v8 P/ ~, Q
  735. /*                                                                                                                                                */- d! j/ c, S% R" e
  736. /* Input:                                                                                                                                */% d0 g3 m9 ]$ h3 {8 R; }
  737. /*                                                                                                                                                */
    / P! ^- @$ D/ b  l& s: u
  738. /*                byte1:                1st byte to be programmed                                                        */* P( S3 I7 b6 E8 ~% T
  739. /*                byte2:                2nd byte to be programmed                                                        */6 u( _$ V& ~! O( c: W
  740. /*                                                                                                                                      */
    2 r" Y3 _& }  U! Z" _& I
  741. /*                                                                                                                                                */
    ' A9 a" b0 J$ G7 \6 V: I
  742. /* Returns:                                                                                                                                */+ s* y) J$ j# }( N' w
  743. /*                Nothing                                                                                                                        */
    + F0 w3 G) V' u3 U  H
  744. /*                                                                                                                                                */
    & \2 L8 F0 X+ j' D. o& c0 K
  745. /************************************************************************/
    : @, ~$ ]2 y8 z* K+ x9 y8 q) i: }! ^
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    : ~% z" N! ?0 p2 ~+ c* @
  747. {
    7 z3 g* l. B0 E  Z' v. k
  748.         CE_Low();                                        /* enable device */
    9 ^/ U8 d' `* R4 a/ ~
  749.         Send_Byte(0xAD);                        /* send AAI command */* s- k" W) _" G7 X
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    ! [/ p, ?+ o4 S, ^5 V4 V
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    1 w0 q3 N/ m# k* ]. _9 e
  752.         CE_High();                                        /* disable device */2 E, P% [( {, A* f6 s
  753. }
    ) y3 t" t5 w) ~' i, s/ Y

  754. " f- W* F6 A# L$ [
  755. /************************************************************************/
    : `) E; {! G* R7 ]2 a) J
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    % }/ d$ I2 H  L
  757. /*                                                                                                                                                */
    8 e, `/ Q. N. Q3 F, f) E- K- q
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    5 ^+ @  ]6 V' ?- l' h" @; y4 v; r
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */; U, m. O: N4 Z0 I' K1 [  f
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    6 L6 c* a& D/ u, {2 V" s/ ]
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    # t8 [! i  J+ l8 l
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    % j- [" A! v! K
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    $ F. J/ j& P2 m, ]- z
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */) X# \1 `% O, l. `. C
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    , Q  \/ d/ m" S" S8 Q! }
  766. /*                                block protected.                                                                                */
    ! H5 L4 i% Y& D/ n) @
  767. /*                                                                                                                                                */
    3 C6 p4 p1 @8 _& y. ]2 w2 ~/ O! p
  768. /*                                                                                                                                                */
    7 a/ V) z+ E0 D0 T, Y
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    4 M9 \$ \! R- Z
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */9 q" R6 V. K9 I; s6 ^" |
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */. n  i: s( A5 I
  772. /*          to exit AAI mode unless AAI is programming the last address or                */5 [: f* d* B( T  N% n0 r! q4 }
  773. /*         last address of unprotected block, which automatically exits                 */# H- }' l, D8 t, p0 d+ I
  774. /*         AAI mode.                                                                                                                        */1 g- X6 x6 ?- E* p1 E# x
  775. /*                                                                                                                                                */
    3 k% G$ Y  B1 A+ ?) H& f' ~
  776. /* Input:                                                                                                                                */7 F' E. d' ]+ z- n/ O" R
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */. h1 f. I2 z. n
  778. /*                byte1:                1st byte to be programmed                                                        */1 j* h; Z+ M* e) w- M; G
  779. /*      byte1:                2nd byte to be programmed                                                        */* \4 w" Z* y" Y' X$ K6 [% Q7 [5 S
  780. /*                                                                                                                                                */# T( t; |  v' o
  781. /* Returns:                                                                                                                                *// M5 T  O& o5 |1 g, Q+ E
  782. /*                Nothing                                                                                                                        */+ q' V, T% W! p* O
  783. /*                                                                                                                                                */
    7 ?4 a$ k. D! b* g1 m% [
  784. /************************************************************************/
    ' k5 `5 r# C* V" a
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)0 U' D: b$ @  \$ z4 E  o
  786. {
    ; V% C/ h7 e5 J* I1 q& H
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        + [6 s8 }  ^! P6 H% K* |% d

  788. - [  A! s% L* @# v
  789.         CE_Low();                                        /* enable device */
    3 K$ R* O  D9 |* a
  790.         Send_Byte(0xAD);                        /* send AAI command */& ]$ V$ l: H4 Q/ [
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */* W4 F$ }& w3 ]1 p$ p1 W6 z2 ]
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));" z  f6 m$ a8 E
  793.         Send_Byte(Dst & 0xFF);
    ( i" h8 @0 {1 c4 q3 c3 P4 [
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    & S) u& l% E. l3 R7 L
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
      \) m7 x; z9 m1 A( S
  796.         CE_High();                                        /* disable device */
    ; O* x1 G$ K+ k' [! s$ y
  797.        
    ' y- t/ x9 L: ~, h0 _9 h, d
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    # n% ?! e4 }2 k6 B6 F- E" b
  799. ! K0 h6 u# i0 I0 I( ?
  800. }) {0 e, t1 E+ [

  801. 9 ^% c9 m8 y* q- A
  802. /************************************************************************/$ U7 S; p/ T0 t* K- |( O
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */. ~* j- b4 q( d$ p  f9 K0 F
  804. /*                                                                                                                                                */" Z* y* S  k5 W) U: f2 v
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */1 I& P- c# j: x+ y, w, j. X
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    8 H: G& b' T$ Z
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    , O8 D9 a7 I& p5 ~8 U- h
  808. /* the device.  The 1st data byte will be programmed into the initial   */0 n' k0 d. A* K5 [" E: y7 E
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */7 b" ?- z: X! {3 u
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */& i7 T, b3 ^1 d  B( h5 x
  811. /* used after Auto_Address_IncA.                                                                                */# E6 m' ~% D/ G( X/ r* M  t
  812. /* Assumption:  Address being programmed is already erased and is NOT        */' r* r' J* h4 H$ ?8 P& \
  813. /*                                block protected.                                                                                */' _  R* q& j, A4 m  D0 f
  814. /*                                                                                                                                                */
    & d) M; d$ v* I! X, y
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */. C% [5 Z' n. t  |+ m) t
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */: p6 i. r! ]- d" Y# x$ T
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    6 E2 Z# d% L! r
  818. /*          to exit AAI mode unless AAI is programming the last address or                */# r% ?+ w' v5 i  m4 J
  819. /*         last address of unprotected block, which automatically exits                 */
    & ]# ?* {/ h: K7 ]
  820. /*         AAI mode.                                                                                                                        */
    6 a$ p8 L& J7 \6 i
  821. /*                                                                                                                                                */+ x. e' k1 L5 n3 q) N
  822. /* Input:                                                                                                                                */
    , B# G0 Y/ c; ^! H0 f
  823. /*                                                                                                                                                */) U# B" Y$ }5 Z; j- g  p+ n7 O# u
  824. /*                byte1:                1st byte to be programmed                                                        */
    8 l% H3 g( Y1 z
  825. /*                byte2:                2nd byte to be programmed                                                        */1 }4 g( @) t8 T+ ^
  826. /*                                                                                                                                      */) {9 L. @+ a- U
  827. /*                                                                                                                                                */3 {/ Q: B! m) H, O- W
  828. /* Returns:                                                                                                                                */$ f5 I7 y1 h( Q% R% t
  829. /*                Nothing                                                                                                                        */
      j2 A% S1 E+ Z" F$ f' `
  830. /*                                                                                                                                                */! w$ Q# n* ?* F5 q
  831. /************************************************************************/
    7 U, ~8 e0 L, p/ O1 a
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    , x! ]5 D1 Z2 e' ], [! f4 ]0 n. T
  833. {
    0 R- y5 Q0 e( n, K
  834.         CE_Low();                                /* enable device */
    ) X& N" f* w* y; E& H
  835.         Send_Byte(0xAD);                /* send AAI command */  S( G1 v; Y. @- m% O# D
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */6 a; }& }4 Z4 Y6 D* R2 V6 O& G
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */; {: a) f8 f2 b. A7 c" X
  838.         CE_High();                                /* disable device */
    7 q6 h; e; M$ e6 `/ E
  839. * w3 t$ p6 U* h# v6 |7 V
  840.         Poll_SO();                                /* polls RY/BY# using SO line */, L) @. G' O8 G# s6 ^4 y
  841. / d  F! H; }( v. i) c; j
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    , U  B2 k. W/ G$ N( E
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    $ R; {4 d6 x3 }  v+ M9 K/ k$ g
  844. }
    2 z( k: p' F1 i5 n, @; l

  845. . C/ V; o  O% J4 M
  846. /************************************************************************/
    : ^6 j% Y# D( f! X1 Z
  847. /* PROCEDURE: Chip_Erase                                                                                                */% H4 e! h7 Z/ m7 E1 l
  848. /*                                                                                                                                                */
    ! d0 U, E2 R1 f& {& n" V
  849. /* This procedure erases the entire Chip.                                                                */$ {3 R% n8 N1 Q  b5 t% h' v5 y9 ~8 l
  850. /*                                                                                                                                                */
    + z2 Y# i5 b: {
  851. /* Input:                                                                                                                                */
    # y& ^" e% `5 V" w; Z4 K
  852. /*                None                                                                                                                        */+ ~- A+ n7 l$ H% U
  853. /*                                                                                                                                                *// h7 c; M/ ?; e# [
  854. /* Returns:                                                                                                                                */9 h0 a% D  `7 S2 L
  855. /*                Nothing                                                                                                                        */
    ( y2 i/ f9 P" }0 m, u2 {
  856. /************************************************************************/
    * s4 v8 x0 c7 ~4 d4 F" g
  857. void Chip_Erase()  o5 v, t+ A; E9 _6 s- L. Z* M0 a
  858. {                                               
    ( T. u  j8 G2 h' a
  859.         CE_Low();                                /* enable device */# K, f0 w8 @" P0 u
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    . _2 u( o5 Y5 C
  861.         CE_High();                                /* disable device */5 X6 q- d' K4 E0 D6 `) [: e
  862. }+ K% R" Q( k9 ^6 o" I$ D

  863.   y6 q* w9 n& k" J
  864. /************************************************************************/
    9 B: O1 Z3 y2 ^; Z: L9 B
  865. /* PROCEDURE: Sector_Erase                                                                                                */7 M- r  ]. m2 \' T7 \* z" y1 X
  866. /*                                                                                                                                                */  l6 }; N3 q: p$ g
  867. /* This procedure Sector Erases the Chip.                                                                */) d# @( |2 a! I0 [: O
  868. /*                                                                                                                                                */; B7 \& R2 o; X# @
  869. /* Input:                                                                                                                                */
    ; x  q3 j" h# q  r2 d) G, H: l
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    5 o& q, V% ^9 l
  871. /*                                                                                                                                                */5 t( U9 e' j/ `+ V' K
  872. /* Returns:                                                                                                                                */
      i. R" A- a: j
  873. /*                Nothing                                                                                                                        */$ V# t. T" v0 l5 ]; R
  874. /************************************************************************/- o% N8 E0 r: z3 V; |
  875. void Sector_Erase(unsigned long Dst)* R( D. @; F6 u4 T! d0 R/ h
  876. {; }# |3 c! D( c/ h1 n& B% A. K7 }
  877. 9 p) C$ j: b' M8 [: m9 u) M3 B
  878. - G, q% n) V6 ]! j
  879.         CE_Low();                                        /* enable device */) V6 i" s; ^! H- J& N& d5 S" d  V
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    * [4 Q5 I: w( v4 Z6 S2 G# ~
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */* C9 L. u/ q1 N& D+ O
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    $ y" ?! k# o6 ~
  883.         Send_Byte(Dst & 0xFF);& N8 G5 b2 ~, B/ I/ b  ?
  884.         CE_High();                                        /* disable device */
    2 ?4 {( o# z# K. o" D+ X, \
  885. }        3 e/ i$ p) W2 i0 C
  886. # W( f9 {6 G8 o" k+ _5 r  p
  887. /************************************************************************/% n/ s3 Q; R$ Q+ `+ X0 D% R9 B: P
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    : ?7 i  o. ^; N2 E# l# o& J- m
  889. /*                                                                                                                                                */+ u+ n& H( N) C3 r( u
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */( Z- {- C/ ^. f  q4 L3 P) c: H
  891. /*                                                                                                                                                */8 z5 w7 x) @/ @& @  ]' {
  892. /* Input:                                                                                                                                */& s+ @3 i; N$ o; w. h
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    7 `8 |5 q) K# S1 c( g6 T
  894. /*                                                                                                                                                */" h7 S$ W; |' c8 c$ S
  895. /* Returns:                                                                                                                                */
    1 U/ t+ v" z9 Y, [/ f1 h
  896. /*                Nothing                                                                                                                        */
    ' a% X9 L/ |, J8 r
  897. /************************************************************************/
    , B' n/ B# [- Y. X
  898. void Block_Erase_32K(unsigned long Dst)5 g; d0 q, R. D, B3 N5 Y
  899. {4 O" p1 `9 }7 ?) Y7 c
  900.         CE_Low();                                        /* enable device */! }8 Q- ^8 ~- b7 m" h
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */# z- g: u1 O0 L0 `! T( ?; z
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */9 i1 J0 Q  g+ Z8 z3 c. E  |
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ( x2 o! {3 |+ \/ g/ m, d
  904.         Send_Byte(Dst & 0xFF);2 m3 v! x% Y4 }: x
  905.         CE_High();                                        /* disable device */, S: X) T: c3 @6 R2 a
  906. }3 s$ V$ F0 h# U) j

  907. # s  ~3 z% G0 _, I+ r
  908. /************************************************************************/
    ! A2 l. t- A3 R- X3 X9 m
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    8 P9 c, h! z& M( ?9 f
  910. /*                                                                                                                                                */! ]8 a* z3 i, b8 q
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    * ?6 N, H# H% f
  912. /*                                                                                                                                                */: `2 d: c! q+ a  T2 u+ F8 N6 N
  913. /* Input:                                                                                                                                */
    0 A9 D" ?0 f" b2 H$ K: g" R4 A
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    # i# r0 \8 w7 ]
  915. /*                                                                                                                                                */7 [0 m- D4 B. g' l1 j
  916. /* Returns:                                                                                                                                */, p) o5 {* ~6 {2 v( G; X/ j2 _
  917. /*                Nothing                                                                                                                        */
    5 M/ z/ i' g) M6 s: w1 p' y
  918. /************************************************************************/
    1 b: X0 K# v. C% Z: `) i. L) z
  919. void Block_Erase_64K(unsigned long Dst)
    1 Q, f/ j+ T* i/ V5 P* f
  920. {
    , g. q6 {8 Q3 n( a) ^+ r7 j
  921.         CE_Low();                                        /* enable device */
    9 H! s. E* Q$ y: \/ t7 H6 P
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    , F- _( y! p. c: |- m
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
      X- G! F; i9 S: ~
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));3 P1 l5 R7 y* ?0 |/ W0 N
  925.         Send_Byte(Dst & 0xFF);
    4 u0 {$ T3 q1 k& L% n. x
  926.         CE_High();                                        /* disable device */4 z. ~5 G3 |% P6 y0 |5 ~
  927. }
    0 I. x: d6 t) @1 R, u5 Q$ u
  928. 1 O, ]9 e0 {6 e
  929. /************************************************************************/
    9 p, J, ?3 X& u/ l7 P5 U" [6 |; Z6 k
  930. /* PROCEDURE: Wait_Busy                                                                                                        */8 S% l! P) Z- |' T2 m
  931. /*                                                                                                                                                */  Q1 s* s6 e/ w5 `
  932. /* This procedure waits until device is no longer busy (can be used by        */1 e7 y" P( M6 y4 g
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */) t1 o, Q( g* h/ C# p* ]8 e! }/ a
  934. /*                                                                                                                                                */
    * V! X1 Y6 Q+ r8 q1 N3 d. H
  935. /* Input:                                                                                                                                */
    $ ~5 y: y# ]; H+ V2 m. q: B# I
  936. /*                None                                                                                                                        */
    ( H1 s0 N0 l% W: s! E
  937. /*                                                                                                                                                */
    , q' e- M8 e3 O; `
  938. /* Returns:                                                                                                                                */
    : m7 l: P+ [( w. \
  939. /*                Nothing                                                                                                                        */  p  E1 M# u( J
  940. /************************************************************************/
    ! s+ Y  F# A& i/ {3 {
  941. void Wait_Busy()' z( N& `4 r$ d$ g
  942. {
    . }8 a& n! @/ v5 d! I5 n
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    1 e  ]: g' f/ \0 I: \' J8 i' E
  944.                 Read_Status_Register();0 Y: ~0 Q, W* M- r4 O" W  F0 m" p
  945. }
    ) i, X4 N' \/ A7 m6 ?

  946. 3 h6 _3 b0 Z# f2 J/ R$ \8 t* V
  947. /************************************************************************/
    . _3 y& F" @7 [5 ?$ C4 R
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    # @" T7 U; D7 u; B* x6 c# I
  949. /*                                                                                                                                                */
    + W; L2 v5 j6 @1 Y! P8 `
  950. /* This procedure waits until device is no longer busy for AAI mode.        */1 {. Y9 D) I9 u8 G% H
  951. /*                                                                                                                                                */
    2 P4 }) q. V, w+ W" d1 O
  952. /* Input:                                                                                                                                */5 g( a  J  F* t8 l
  953. /*                None                                                                                                                        */
      _4 s, ]- R/ t9 B2 Q& |2 z
  954. /*                                                                                                                                                */' o" n( O: r" o8 m( R; a
  955. /* Returns:                                                                                                                                */
    , V, e1 X$ k( v( @3 r) c# M4 M3 [0 u( o* c
  956. /*                Nothing                                                                                                                        */# L( D. _; r/ {/ ^
  957. /************************************************************************/
    ( ^# z$ q2 G, U* |- k9 `9 c& E2 C
  958. void Wait_Busy_AAI()
    ! s9 g; w4 L8 D
  959. {
    9 \, Q) z3 W3 }" K
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    : M( c  p8 Q% O/ V1 i* r4 d
  961.                 Read_Status_Register();
    & v8 H. [! S! `  G# {# J
  962. }# N) {3 T1 s) m0 N$ i# O
  963. ( M% @+ g# [/ L) k
  964. /************************************************************************/
    3 L6 j  p! ^5 h0 ~5 }6 V) d1 w
  965. /* PROCEDURE: WREN_Check                                                                                                */1 e/ q! {3 p2 B1 z
  966. /*                                                                                                                                                */# b9 w9 _6 g1 ^- E
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    : Q$ r# r; ?7 c2 S4 b% O1 S
  968. /*                                                                                                                                                */
    ( ^- Z% H- j6 @- v/ R
  969. /* Input:                                                                                                                                */
    & @2 g5 d7 Y9 S/ ~
  970. /*                None                                                                                                                        */2 M) z- N/ G( x9 D* a0 r! R
  971. /*                                                                                                                                                */
    3 K2 |& m9 m, m8 G2 R3 g
  972. /* Returns:                                                                                                                                */; u; ?, `+ [/ |# ~
  973. /*                Nothing                                                                                                                        */
    , y6 G6 K* i! g( [( c2 N3 h* e
  974. /************************************************************************/+ \; N& f6 \+ J/ @) i0 O
  975. void WREN_Check()( s* A; t1 N% f2 I; H6 z
  976. {
    ' U' H& h7 F( T2 Q+ U
  977.         unsigned char byte;
    , E+ ?7 D5 d5 K: Z' E* T( d: r
  978.         byte = Read_Status_Register();        /* read the status register */( ]2 X: j& T. b
  979.         if (byte != 0x02)                /* verify that WEL bit is set */3 t2 I1 d3 q& C6 `: }9 P  Q* C& R
  980.         {2 B# |, Q3 w8 |: A
  981.                 while(1)3 s  {3 \7 q' i2 f
  982.                         /* add source code or statements for this file */: D+ O/ U2 {% @/ r# A' h2 F" x
  983.                         /* to compile                                  */0 b7 f3 o+ w2 l- {
  984.                         /* i.e. option: insert a display to view error on LED? */
    5 N) M$ G, r% m' s- |
  985.                  % z4 t: X: E1 g
  986.         }3 |! G9 e* N- {$ d% d) K) t
  987. }7 k! ~* v$ u: m
  988. ! [4 I* `6 g& ?! A
  989. /************************************************************************/
    0 o% y* `! f! o
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        *// q8 D5 L0 u: S3 `3 d+ O
  991. /*                                                                                                                                                */+ h! Z( A0 Y& T, }! n7 ~2 k
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    ; @( {1 n: b/ @
  993. /*                                                                                                                                                */) f+ N7 d0 r( T9 z4 l7 z1 t
  994. /* Input:                                                                                                                                */
      t! Z* p# f, a# F6 F
  995. /*                None                                                                                                                        */
    + O( ]' j7 J4 W4 o
  996. /*                                                                                                                                                */% l' f' n0 |6 b
  997. /* Returns:                                                                                                                                */# c2 l4 M" P" e$ `- R  v
  998. /*                Nothing                                                                                                                        */
    ! K  k8 [+ L, p" K- D/ ]  F
  999. /************************************************************************/
    1 K. p: |- B7 ?' C2 R
  1000. void WREN_AAI_Check()
    * j0 n  T0 x( g) B1 x
  1001. {' K) x# ]' j5 X$ |
  1002.         unsigned char byte;% d# l: e! m" w& v+ T
  1003.         byte = Read_Status_Register();        /* read the status register */& C0 Q/ G% w. ~2 Z  g
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */$ a  x8 [; I5 S0 Q
  1005.         {: l' }0 @2 @. B. T9 [3 f
  1006.                 while(1)               
    & X4 n: I; N. \; Z4 F% V7 ?) ^3 F+ A
  1007.                         /* add source code or statements for this file */0 e% s+ i  U4 N% n9 v1 ~/ G+ M& I
  1008.                         /* to compile                                  */
    3 R$ s) m2 i, e+ T  v7 A
  1009.                         /* i.e. option: insert a display to view error on LED? */
    8 ?4 [, j5 F/ s& ~
  1010. : y0 D0 @. d% Q! n
  1011.         }) D5 m6 k' [3 Z8 M) T& W) p
  1012. }
    ! d5 J' {* R$ L# @$ [  b% R8 G( e
  1013. : l1 N4 q3 \4 O8 P& |* ]# Y  K
  1014. /************************************************************************/& u/ a; t( P4 Z8 h
  1015. /* PROCEDURE: Verify                                                                                                        */9 J& h) V; t4 U. B& c- Z2 c6 ^8 L* F
  1016. /*                                                                                                                                                */
    5 \3 d; ]" J$ s' @8 \$ {
  1017. /* This procedure checks to see if the correct byte has be read.                */
    ) M  p* P* c4 A
  1018. /*                                                                                                                                                */
    ( g5 Y$ p1 F7 @0 I0 e- _
  1019. /* Input:                                                                                                                                */
    , _( l6 P: l& }% J
  1020. /*                byte:                byte read                                                                                        */
    ( E  M1 Y# r* C. Z" H& g
  1021. /*                cor_byte:        correct_byte that should be read                                        */: u: r% }5 e7 K
  1022. /*                                                                                                                                                */
    * `8 q0 Y- E; Q3 `6 Q
  1023. /* Returns:                                                                                                                                */
    2 ~; `" u& A5 Z) j: V
  1024. /*                Nothing                                                                                                                        */
    7 h0 Y+ w( g6 ^, {8 F
  1025. /************************************************************************/
    . v0 K* P! M7 ^& g9 M0 ^9 E1 d; H$ [" e
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    2 {- `" M' F; i; F; q$ ]2 ]$ e
  1027. {
    ( n. @6 O3 t  }$ {' C9 P
  1028.         if (byte != cor_byte). i$ B, M' n, A, {0 U
  1029.         {
    8 y- m4 |6 u7 {3 v. S: c  ~, W
  1030.                 while(1)
    % o' g2 z1 n- K! y. k
  1031.                         /* add source code or statement for this file */
    " P) e. _' H* a& ^
  1032.                         /* to compile                                  */+ C' @+ Z4 o/ @5 x8 Y
  1033.                         /* i.e. option: insert a display to view error on LED? */
    " T6 |0 {+ F& t4 w# d. p$ [
  1034.                
    1 H- s1 N3 W* x9 g/ G% L
  1035.         }
    ) j0 X; \& X3 n, ], Q$ L
  1036. }$ z2 Y3 v& `# c# e5 q
  1037. ( K# L8 W' j& h/ K0 J. ]$ h* s  c

  1038. 6 s# i* ~7 z+ Z. I1 V1 D+ W, z
  1039. int main()0 c" |7 m5 ~0 r. N8 z; m$ X
  1040. {
    8 r2 N6 O: }: |" ~# v& ^
  1041. . D& o( c" ~1 _1 I, i
  1042. return 0;
    2 r: a! V1 u% U2 E- E& J8 Y
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
5 K; p7 j; E. a8 Y" x& \' q1 ?   main(): `! W/ o8 o; o8 a& e8 p, e$ j
   里面怎么是空的呢?
* ~7 P- p8 g( X   发一份给我吧; w" V8 k$ \# y$ E. g2 t" R
mail:luyijun2005@hotmail.com* z" U! I1 K5 u4 G4 ~9 E3 S
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。0 B4 E* ~+ b" j" F% u( a. i( R9 M

) ?& m' a$ w: D2 J[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
& J! ]* `/ }# c. ^% o8 v/ oEC的代码在哪跑,你看DS的说明,每个EC都不同的。
; ?' b3 n% K, o6 X8 D+ R2 BOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?8 {6 z" ?8 r0 Y! B& I0 G5 k1 G
上面几个问题是你没看任何东西而白问。8 h) J! j  @. X5 ]) Z! ^! b2 s! y

! P8 k6 g% _" M6 d* N" m" X至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
$ A3 L) [; F! k! H% w' i/ @( j) R5 [1 @& ^* y) }$ G( b* D
关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
# o* ]' `3 J' j& p2 {
) Z1 [1 P+ ^9 I! W关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”! w* E4 O- V, c( u( x
4 I/ L& U7 q) O7 f  O
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...% {: n! ?" Y3 o( L% [/ V" ]
% z, N/ |% L0 Z: o* B
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
5 p' v3 v! D6 ^$ ^似乎要把SPI能support 到最大,这EC chip应该有好卖点
( }. [) N) v8 I( ]BIOS功能要不要强大,也就决定了SPI Flach的大小
- D1 t( j/ D% M我是这么想的~让OEM去决定要挂多大!
' P, e, f# k* h* c5 u' U如果我司有BIOS工程师就好了~哈
+ E5 |$ P* U7 L6 n7 L0 v) m! q" oWPCE775应该算很新的东西,来看它支持到多大?
* ~5 [$ D$ J; M% o- \: E8 D
; {; o* b3 d( l7 b. o另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte4 D- I7 }" W' P& W+ P" Y! W5 y6 z
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
& I3 V2 n, U& f4 H" D, K6 s, B' ?# K' g0 _  M2 R$ Q
这份driver收下~希望以后有用到
9 g; Q$ F8 v# l; N0 P- Q谢谢bini大大
: ?* |- R& a( D5 s( M! C& S. b
: P2 |9 D* W* f, l! D很新很新的新手,如有错误请指正 (准备看第二家的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()
' R" O# i" a% J7 e{% ?  f* g, m+ ?, B
        unsigned char temp = 0;" {7 d3 G1 d' C
        CE_Low();9 _0 Q& y. M: ~
    while (temp == 0x00)        /* waste time until not busy */
! s/ T9 b3 M# i0 M5 g                temp = SO;
& y! f! _. m3 R" u  H4 M        CE_High();
. ?& K5 T% j6 Z" F+ V0 [: o}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
1 B3 ?4 a2 U8 ?{  W3 K( t& M! d, E- o
        
5 Y, N' W0 a" ^/ s% K        unsigned char i = 0;
, f, v& |! z; O( P        for (i = 0; i < 8; i++)$ g* D  V+ `5 h' U; z& I0 y2 d6 j5 N$ T
        {. q) e$ l5 D7 t* t, @% {
               
+ T2 }1 v8 b, }) o! A' ]                if ((out & 0x80) == 0x80)        /* check if MSB is high */* U  E: r8 s* H6 |# h! Y
                        SI = 1;# s+ j6 n7 u6 n! P
                else
% x0 k$ F$ K; M) |( k0 Q' t                        SI = 0;                                /* if not, set to low */6 @) L$ x4 l' ]$ J* _
问              SCK = 1;                                /* toggle clock high */' S$ r1 p6 J3 _" `
   题            out = (out << 1);                /* shift 1 place for next bit */% ]! n2 U6 I" K( z) I
                SCK = 0;                                /* toggle clock low */
! a% q3 k. |# j" j6 G        }* N3 j/ G- C+ K6 h5 `8 _
}
* K- }* X8 D/ ]) p* T 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-2 02:08 , Processed in 0.036901 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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