找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54889|回复: 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 Driver8 T1 Q6 e. {0 d8 j9 C8 h
  2. ) Q$ v) Q6 q7 I, ]9 V! }# h+ L3 S. a; y
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    # o* L% |" P; ~6 Z* ~* k# j

  4. ' K4 V% ]/ T  ?5 T9 h( g4 `
  5. November 4th, 2005, Rev. 1.0' \4 \, |; l5 M2 a; c; b" H( l& M

  6. 2 g, C  h+ P" c4 g; b
  7. ABOUT THE SOFTWARE
    2 y$ L5 g, K8 ]& h% [' d! c: V4 R
  8. This application note provides software driver examples for SST25VF080B,7 s, n7 ^& @) L
  9. Serial Flash. Extensive comments are included in each routine to describe
    ) T  S& R5 s  A. _, F. m
  10. the function of each routine.  The interface coding uses polling method
    * u5 B9 v- @) W; W$ m7 I2 f
  11. rather than the SPI protocol to interface with these serial devices.  The8 ]9 D& y9 z: r. m
  12. functions are differentiated below in terms of the communication protocols
    ! t6 o; u& k& @6 P
  13. (uses Mode 0) and specific device operation instructions. This code has been
    / B$ m+ S/ J1 q" }5 W) T( j" @- C
  14. designed to compile using the Keil compiler.6 @* g6 c3 f9 x7 l% _! h
  15. 8 K* q: s+ v3 M4 J7 o
  16. 4 l  ~3 K/ r3 D$ r4 z
  17. ABOUT THE SST25VF080B
    % s. e' Z% w  q2 E' t& B5 E8 s

  18. + f' {. {' ]' Z! S, c
  19. Companion product datasheets for the SST25VF080B should be reviewed in * i/ F2 ?) f- ^
  20. conjunction with this application note for a complete understanding 7 e3 a+ u* n2 N8 o- {% w# \$ o& B
  21. of the device.
    ) k6 f2 O; a- r% R
  22. 0 ?3 Q2 x: H) r, n7 E1 A

  23. 5 B$ K5 }( A) c3 V+ o. d
  24. Device Communication Protocol(pinout related) functions:
    , x; \2 i: o9 G

  25. ! R  o5 G4 [, Z' r! `
  26. Functions                                    Function
    8 R8 W7 f5 I6 \8 P5 d
  27. ------------------------------------------------------------------
    - F" W7 b1 H! u; s0 q1 e
  28. init                                        Initializes clock to set up mode 0.; ~: e& T& |7 a/ E
  29. Send_Byte                                Sends one byte using SI pin to send and + U' c7 X6 k7 C8 E9 ~
  30.                                                 shift out 1-bit per clock rising edge
    . s: v! o+ X5 [' y* G1 _, `* D
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    & c8 h4 {( m8 u# t# T: `
  32.                                                 in 1-bit per clock falling edge5 \: n1 Q. N+ {4 A# p. h! s
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming" E$ Z4 o! D: f$ p5 U/ R
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    , V; r1 q' F, d# l* O, u# g
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    ! o2 L3 \0 o9 J4 Z2 W
  36. Hold_Low                                Clears Hold pin to make serial flash hold5 C; ], l1 z* P. o; o! j) ~
  37. Unhold                                        Unholds the serial flash& `: a* _6 V. X  k) i6 `
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    . t. f2 x* t$ \$ B9 H
  39. UnWP                                        Disables write protection pin
    + v1 o) N+ v$ a6 X' S7 b  K8 X
  40. ( A( M  G, Y' d  B8 w: `$ q& D
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    + M1 T6 g0 g* O* b" a
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your% l- f9 A, c- F1 A
  43. software which should reflect your hardware interfaced.          
    ( e3 r# ^0 M& C, ^; g

  44. & b. w9 t+ z8 g6 k' V6 c
  45. + g7 l# \  N) B4 G/ \
  46. Device Operation Instruction functions:- |+ l& `" u/ n$ |2 A

  47. ( }' f/ a6 `- J9 b) b) o
  48. Functions                                    Function
    9 U5 X: \3 _" g) w) d
  49. ------------------------------------------------------------------
    5 L6 ]% Y- D4 t& r. z
  50. Read_Status_Register        Reads the status register of the serial flash
    - ^2 U! o3 y7 i' t
  51. EWSR                                        Enables the Write Status Register2 y+ @: O$ x- \0 T+ c& R
  52. WRSR                                        Performs a write to the status register
    ' ?! D- m  c% u+ p- O
  53. WREN                                        Write enables the serial flash2 `8 R9 q, s3 Z
  54. WRDI                                        Write disables the serial flash' \0 S3 P' W' _% U+ Q9 e- n
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming
    ( I0 T9 O( V' K
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming) w2 T) r5 V% }7 L4 Z& x
  57. Read_ID                                        Reads the manufacturer ID and device ID
      k5 v9 N" {$ u1 H
  58. Jedec_ID_Read                        Reads the Jedec ID
    4 I- l  y6 E8 ~9 j2 R
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)+ ]) N) z. u5 I; s& h# J, r0 ~
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)8 b0 w5 y6 F1 C( m- S8 c
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)/ l7 A$ y* E) d. p) z
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    $ `% u- S' l5 [: d: Y# O, i* X4 l* t
  63. Byte_Program                        Program one byte to the serial flash+ f' x) {  H1 s; [4 C; }+ Q
  64. Auto_Add_IncA                        Initial Auto Address Increment process& g$ e" l" q+ @) y9 ]
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation1 V; P. O* Y% w" x9 u
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    # m& U8 E' [/ }) Z! Q
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    3 ], N& l4 X+ t4 _3 a
  68. Chip_Erase                                Erases entire serial flash& A) B! u9 d5 }  u( c8 m5 N* o
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash6 i! w- ?; k4 ]+ G, m
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash0 A6 t" l& b2 A2 A! O+ `: r
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    ) a7 i5 x3 M7 c6 i6 D: D
  72. Wait_Busy                                Polls status register until busy bit is low( Q1 {6 u8 `/ b
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming# w% g+ |8 t9 h2 P
  74. WREN_Check                                Checks to see if WEL is set$ Z0 d9 s% Q* y8 O2 i/ T( j
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set; _! b" a& ]: t# e/ F  P
  76. & m- O% `9 d: y; x$ {4 ]" _- q

  77. + f) l: a( u! S( V
  78. $ E6 j- `: D1 y6 w
  79.                                                                      6 k) E% b2 j9 M1 v5 z! o9 p' x
  80. "C" LANGUAGE DRIVERS 6 @) v- X& X- w7 S8 E/ q
  81. $ Y! g+ K) c/ D; }
  82. /********************************************************************/1 O7 f7 R" o; d! K% J- ^. G" B
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    ) U# u* L. a) S9 \
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    $ D' n4 U' h; S5 {
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */% t( N; B6 A$ Z, A
  86. /*                                                                  */
    % Z: G/ d8 d3 I3 l2 T
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    0 M) [& h6 Z4 U7 t' o
  88. /*                                                                  */  G) D+ Q4 M/ f) X# c
  89. /*                                                                                                                                        */
    ; H5 d; t+ m: \9 E8 K- C9 r
  90. /********************************************************************/. V) i: x3 M# T: f# [! F
  91. $ b1 _1 N& h& M0 g6 w: V1 d* A
  92. #include <stdio.h>
    : S7 s0 D' z/ j: n5 X: W2 X- j& `
  93. #include <stdlib.h>% A* M& \/ Q3 c# a' `
  94. ; l4 _* I( v6 z/ H) c
  95. /* Function Prototypes */8 A  _0 G  L* T( T% [
  96. 1 T: g6 ^* ?% Q5 [) M# L
  97. void init();) b1 [  ?& {5 J; r
  98. void Send_Byte(unsigned char out);
    % M3 o, l+ {( c! f
  99. unsigned char Get_Byte();
    3 b7 e# ^) ]) Y, j6 `* s1 Z7 s: r
  100. void Poll_SO();
    & J( }9 y: k+ {- x0 r: h, p# i
  101. void CE_High();% ~5 C6 l1 i) I
  102. void CE_Low();
    - c2 v3 c; c# c1 g9 L: w, p
  103. void Hold_Low();/ S7 C( Y  {7 [% i4 _
  104. void Unhold();
    . d/ p+ m; p  b+ G
  105. void WP_Low();6 J& ~2 ?, g1 ]7 R. Z" J
  106. void UnWP();3 [: j+ Z- U- e# O7 G
  107. unsigned char Read_Status_Register();7 C: \2 q4 m! j8 D3 {. A
  108. void EWSR();6 t% j8 u% f- p0 G0 u! P* r5 R& D/ Z
  109. void WRSR(byte);
    8 i* r2 b% I& p, {
  110. void WREN();
    8 H/ C1 G2 I7 i8 B, ~' W
  111. void WRDI();* O! a! ^# X0 K, K' F: v
  112. void EBSY();
    - @4 [) M9 Y. y7 @) o! [0 m
  113. void DBSY();8 g1 M$ O5 Q# P: p3 O1 E
  114. unsigned char Read_ID(ID_addr);$ W- X5 I/ |% F
  115. unsigned long Jedec_ID_Read();
    ; ]1 D3 k7 M) B& t$ C2 |& c8 R, Y
  116. unsigned char Read(unsigned long Dst);6 [* G& Y1 A, j. E  l: I
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    , P, n7 s% q3 u
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    9 {, ^. q  b% }
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    * |* W- ?7 t2 @. C% h7 ~5 t9 O
  120. void Byte_Program(unsigned long Dst, unsigned char byte);
    ' S0 n7 W1 ~2 i, Z$ u5 p* j
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);$ \5 G* v' X  U5 W' L7 j& e4 F3 N% e
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);1 y& c' G) z) ~9 }
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    ( R% r0 Y# V# F+ }; j8 R
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    1 p/ O* p6 V# s+ \8 X0 I8 y
  125. void Chip_Erase();
    - Q4 D7 O$ k3 p" D
  126. void Sector_Erase(unsigned long Dst);+ Q8 N5 e) u/ m$ Q$ x
  127. void Block_Erase_32K(unsigned long Dst);
    ' Q5 u  _- |3 t# [* e+ P4 Q5 a& P
  128. void Block_Erase_64K(unsigned long Dst);, W* j9 h6 X% U8 v- m
  129. void Wait_Busy();4 \1 Z, b8 r: K% l) E$ O5 I1 [9 ?
  130. void Wait_Busy_AAI();
    # G: `- V1 u. B" }7 n: W
  131. void WREN_Check();
    8 q7 a5 n- v# T# H
  132. void WREN_AAI_Check();
    ! z$ V/ n, x  E( E) W
  133. 2 y4 E' T5 e0 w, \3 n0 [! E
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    9 D. {6 c' |: e

  135. 9 w( Y& Y1 U* o% H4 B
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    - \% _& n* o+ r1 h( s% d
  137.                                                                                 /* to upper RAM area from 80H - FFH */2 V" |- k* f$ g6 I
  138. ) B5 z8 ^3 r8 a' f% ^
  139. /************************************************************************/
    9 s2 Y9 z( I/ A% |9 M! @9 l) o& r/ \4 K
  140. /* PROCEDURE: init                                                                                                                */
    7 D) G) J; Y2 @+ v5 J
  141. /*                                                                                                                                                */
    + N3 z& o7 `2 x" |, G9 Y/ _
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    $ {# w( H7 h# c  @
  143. /* setting up mode 0.                                                                                                        */
    - a2 l/ O4 {2 h% Q7 q$ ]! z: i& @
  144. /*                                                                                                                                                */% w' x9 R! E$ l; w
  145. /* Input:                                                                                                                                */. [% A' h* \) X$ @/ Y$ S
  146. /*                None                                                                                                                        */
    + j! R; O3 G" Z; _( n
  147. /*                                                                                                                                                */
    ( n# i' B) d) ~# V% N5 t) K
  148. /* Output:                                                                                                                                */2 l$ t6 U  y- |. u
  149. /*                SCK                                                                                                                                */! m0 e3 t! `, i) h
  150. /************************************************************************/8 \7 B1 O3 E; i1 |/ ?9 ]8 u
  151. void init(): _' a  |+ S4 k2 e4 e
  152. {5 ~( c- q4 H7 P, M7 \$ l
  153.         SCK = 0;        /* set clock to low initial state */
    ( e% g5 M" n2 \3 ~
  154. }
    * u& \% t2 X1 R, v) U

  155. # C  N4 B! @/ k. X
  156. /************************************************************************/
    ; v+ P8 u2 Q  _0 r( G
  157. /* PROCEDURE: Send_Byte                                                                                                        */* Z+ {% o$ G, J+ z4 R
  158. /*                                                                                                                                                */
    4 @- O0 O4 Q/ D3 o9 Y7 y
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    " h6 J# p$ ^+ q4 S; F4 t- U9 q- C
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    6 x/ j% j+ X1 h/ C1 \  Q
  161. /*                                                                                                                                                */: E, E# m% x( W( p
  162. /* Input:                                                                                                                                */
    5 W' ]5 |2 S, l
  163. /*                out                                                                                                                                */
    ) p! i( U5 i1 U' y! h) F
  164. /*                                                                                                                                                */
      _4 e: @. P# S, o6 z5 |/ _4 O$ }
  165. /* Output:                                                                                                                                */  [7 [" b  V/ u8 Y9 R% Z5 u5 T
  166. /*                SI                                                                                                                                */  S" X  ^0 @" ], l
  167. /************************************************************************/
    3 J8 p4 a7 z0 W2 C, A) d
  168. void Send_Byte(unsigned char out)
    ) F- z" h7 N, ?& ]) u4 _; [
  169. {
    6 F8 F  ~% Y5 G; u5 S2 _
  170.        
    1 c; l; T6 ^$ u0 u2 ^+ P7 S" _
  171.         unsigned char i = 0;8 d( n- ^$ j4 H' z! N
  172.         for (i = 0; i < 8; i++)
    5 s7 @8 M9 T' s6 L2 z4 x9 I  d
  173.         {
    . D4 x% r1 G: w+ j/ X- l* o- C
  174.                 : b( \$ g  P/ w, A1 o& d% Y# C
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */$ r  `7 W/ Y& z7 ~
  176.                         SI = 1;* [1 a* a8 P7 a5 y1 \: S  \
  177.                 else! J$ C1 t0 }5 P; j0 x
  178.                         SI = 0;                                /* if not, set to low */
    ' {) s7 D# z/ j' O, z# D# H5 h
  179.                 SCK = 1;                                /* toggle clock high */
    ' M/ s  H( ^  C6 A+ A
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    * N5 F( K4 [  |! h
  181.                 SCK = 0;                                /* toggle clock low */6 `$ N" q& E) l5 H+ l- T% X. N. G
  182.         }
    7 `& v- O1 U4 B# v0 M; X
  183. }
    ( W1 N8 Q1 M) f( _8 ~
  184. 3 z" v* P* d. j
  185. /************************************************************************/8 X) P1 u8 H, c* E
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    % R* _/ P0 t/ F: Y( Z6 p/ S* d
  187. /*                                                                                                                                                */+ U" r! d' B, ~) g! O1 W. N
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */. H, D) F! q: F% M
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    2 k4 }# c' j* o, _9 r
  190. /*                                                                                                                                                */. A  D1 g. ?3 L# F3 i& X
  191. /* Input:                                                                                                                                */
    ) T8 m' E7 f1 N3 d5 W2 l
  192. /*                SO                                                                                                                                */. k7 }( ]# K, ^9 O5 o+ C; u' J! F
  193. /*                                                                                                                                                */' U$ p4 w& P; z* L
  194. /* Output:                                                                                                                                */, u0 V' P! z2 x1 }6 J1 I
  195. /*                None                                                                                                                        */
    6 U# x2 l# [. H# ]. V0 v; G
  196. /************************************************************************/' Z( j( M4 c9 P, g& W
  197. unsigned char Get_Byte()0 J2 d) w7 t) U
  198. {! k5 V6 L0 f9 y# D$ C3 D
  199.         unsigned char i = 0, in = 0, temp = 0;( S( H" P8 ?$ J: G# g% U1 y. q. A* b
  200.         for (i = 0; i < 8; i++)
    8 Q7 d) t. @7 t9 X' g( _4 w! f
  201.         {! e0 ?, y6 {, T2 C
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */& H+ v- b6 s; V; _2 r
  203.                 temp = SO;                        /* save input */
    , _1 N8 ~4 f9 H7 s$ }( Z5 E- Y7 o
  204.                 SCK = 1;                        /* toggle clock high */
    * r: C9 a7 m9 `0 `5 A5 [
  205.                 if (temp == 1)                        /* check to see if bit is high */
    4 M$ [7 `# g4 r- V9 E
  206.                         in = in | 0x01;                /* if high, make bit high */' Y- H" H8 p5 G& U- }9 {
  207. 1 C+ v$ J2 L5 j( f, l7 Q
  208.                 SCK = 0;                        /* toggle clock low */
    % L( k* D. q7 H7 x- z7 Q# H" i
  209. ) w' M* V8 c% f6 ?
  210.         }
    - v1 ~) j) t2 ]7 d' {! V
  211.         return in;
    5 m. J' K, L4 J5 W) z* @
  212. }. e+ ]# M$ d3 G+ u' T# j6 C" n
  213. 7 @# B7 R: F; C3 _4 P1 \* x: l( ^  U
  214. /************************************************************************/
    2 m, g) q  R: ]3 c& p8 p' `' Q
  215. /* PROCEDURE: Poll_SO                                                                                                        */% l3 c9 E  A. A% k# s
  216. /*                                                                                                                                                */
    5 G' f. u: @  S3 z
  217. /* This procedure polls for the SO line during AAI programming                  */
    : `% O. E  \) Z; ]. e; b$ ]2 C
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/7 `; g3 G& h! r
  219. /* is completed                                                                                                                        */
    ) E1 s* A; _& [0 i! C# O9 ?! q
  220. /*                                                                                                                                                */
    , i& [1 H1 j5 Z
  221. /* Input:                                                                                                                                */
    # G- F4 O! c5 V6 J. i' X
  222. /*                SO                                                                                                                                */
    0 i4 A- u/ N- }) b
  223. /*                                                                                                                                                */* D! r2 X; {) o3 `
  224. /* Output:                                                                                                                                */, R" ]4 l0 A! O) @. k! J/ V2 m6 }4 s
  225. /*                None                                                                                                                        */
    * c* }9 k) f7 l7 d+ h0 Y
  226. /************************************************************************/7 X' G; H/ y+ X5 W
  227. void Poll_SO()
    2 z! h8 l; D* \5 k2 Q! R  [7 U
  228. {- R, t8 w6 q- I( z8 j- R
  229.         unsigned char temp = 0;5 l6 g' u- ?0 u
  230.         CE_Low();
    4 O. J' N6 Y! i5 g
  231.     while (temp == 0x00)        /* waste time until not busy */* c: q6 o6 c7 w7 K% q, }
  232.                 temp = SO;
    ) z6 H+ d5 O% L9 K- I; h
  233.         CE_High();
    9 c$ m) s7 q  M/ L, f9 L
  234. }5 Z6 j4 s, w) a; i7 U# i
  235. 2 @+ X! d# m8 w
  236. /************************************************************************/; ~" P( P% o' h7 f
  237. /* PROCEDURE: CE_High                                                                                                        */
    * q0 b# u% @0 c5 U' J
  238. /*                                                                                                                                                */: r: B! H% D( t- D. G5 K! {- T
  239. /* This procedure set CE = High.                                                                                */
    % R( N( \& z8 {; @
  240. /*                                                                                                                                                */
    7 C" Q  c2 k7 h  a. V; D9 W
  241. /* Input:                                                                                                                                */# l' o7 @# k# @& \* E; A
  242. /*                None                                                                                                                        */4 @! Z5 ]( X7 {7 O
  243. /*                                                                                                                                                */" }& b1 S7 H7 v3 z7 {
  244. /* Output:                                                                                                                                */9 b7 S. R( V: _" @4 S- P
  245. /*                CE                                                                                                                                */7 P# R+ Y; p  R" M! R  I
  246. /*                                                                                                                                                *// v. X9 X- u7 M
  247. /************************************************************************/1 ]: P4 }: o0 i2 A0 X
  248. void CE_High()
    , R2 T  Y) E  m2 A% a5 N; ?2 R8 V. E
  249. {
    " \6 r% f( c. r3 y# e# v4 @
  250.         CE = 1;                                /* set CE high *// g  ]0 g; o) q/ ~) P6 c
  251. }; _6 h0 G6 Z5 c) `; J9 V  |
  252. $ k  Q, b4 t- X
  253. /************************************************************************/$ {5 i# B' D) y9 Q9 b* u
  254. /* PROCEDURE: CE_Low                                                                                                        */
    / v# S8 [/ P9 M$ [+ [* B
  255. /*                                                                                                                                                */
    + l2 D' y8 y# L6 a$ K! H+ ]
  256. /* This procedure drives the CE of the device to low.                                          */, L1 d, M( h2 k! @( \, o
  257. /*                                                                                                                                                */
    5 F4 _/ {( M. g! a3 Y
  258. /* Input:                                                                                                                                */0 m% z4 s! y& ?4 E; A# }% ^
  259. /*                None                                                                                                                        */
    % L+ q- U8 e1 M
  260. /*                                                                                                                                                */
    1 X2 b; L6 g# V2 y  P  W
  261. /* Output:                                                                                                                                */) g5 O" b0 ^! z' {
  262. /*                CE                                                                                                                                */
    3 e" h* ?# ]1 d5 P5 V# ?
  263. /*                                                                                                                                                */
    * h0 b6 E# y1 O9 t, r, c
  264. /************************************************************************/6 {& T; [! [( Z/ T
  265. void CE_Low() : W( n9 R* }! @5 E
  266. {        + a. y- }% ~$ I, D# H
  267.         CE = 0;                                /* clear CE low */
    . M  P5 Q1 B% E# V. v* A* |+ Y
  268. }7 u) }. r( d# j' B0 s$ w1 c* r
  269. 6 y( C- \* A# a3 g
  270. /************************************************************************/
      h! T' j% C/ z
  271. /* PROCEDURE: Hold()                                                                                                        */
    $ T1 |0 p6 J6 u+ Y9 C" D" u7 |
  272. /*                                                                                                                                                */# H. u2 V; r7 `/ w# c
  273. /* This procedure clears the Hold pin to low.                                                        */
    $ \# X& r- ]; D2 g, X) K
  274. /*                                                                                                                                                */7 \# ^* X3 j2 g: ?
  275. /* Input:                                                                                                                                */8 y' J9 A1 O. f; r. X7 q
  276. /*                None                                                                                                                        */
    1 L: F: p2 H' Z% |9 h
  277. /*                                                                                                                                                */, w5 I% N& ]& ~) l* V3 p5 D% L9 B
  278. /* Output:                                                                                                                                */
    ' v' o' t. V9 r$ F
  279. /*                Hold                                                                                                                        */
    + m4 L# i7 [" J3 _
  280. /************************************************************************/; s- S9 u9 J+ X1 g4 m1 r
  281. void Hold_Low()
    7 N7 O4 ~/ ^) x$ t" S3 M
  282. {
    ' s; p& D$ r2 x( U  e1 f; Z6 s- ]
  283.         Hold = 0;                        /* clear Hold pin */- M( m4 ?( r, Q: B9 }
  284. }
    5 j/ M' h* q3 S! G- b
  285. # ?: ]$ E, }8 J# I" i' j
  286. /************************************************************************/
    0 E1 d/ Y, f1 g* u. ~
  287. /* PROCEDURE: Unhold()                                                                                                        */5 O9 H$ ~6 S3 |+ j% v) Q
  288. /*                                                                                                                                                */
    0 ?% f6 r0 s5 i, I5 a' N6 m- `
  289. /* This procedure sets the Hold pin to high.                                                        */6 @  t7 f; V8 }6 z7 {
  290. /*                                                                                                                                                */
    6 T) W2 M* R. h3 J  W2 w1 i
  291. /* Input:                                                                                                                                */
    ; E9 k; M0 n( N4 u1 b
  292. /*                None                                                                                                                        */
    ) r" h2 }5 E6 Q) m+ [
  293. /*                                                                                                                                                */% K# M  i2 q, B  }6 P" j
  294. /* Output:                                                                                                                                */
    " x, B5 S/ r/ M8 u
  295. /*                Hold                                                                                                                        */
    ! A, \' T  V. T& d8 E9 Y8 |
  296. /************************************************************************/
    ' |1 ^* L6 @1 ]+ U
  297. void Unhold()/ ]( |" I: T& J5 y1 L* w
  298. {& Z- Y1 D& C! F4 N) C  f! N( O9 u
  299.         Hold = 1;                        /* set Hold pin */! m  e3 r: o* w) O1 e
  300. }
    0 g1 i3 V) [( W0 p5 v8 ?
  301. . j; k2 J2 {" z; a8 Z6 ?
  302. /************************************************************************/
    # A+ l+ e- Z7 n
  303. /* PROCEDURE: WP()                                                                                                                */4 }$ W! z1 w6 z
  304. /*                                                                                                                                                */; T" y9 e( g: B$ P, t0 Y4 Z' x
  305. /* This procedure clears the WP pin to low.                                                                */
    : g# t" e# i& K" ~" A
  306. /*                                                                                                                                                */5 W5 d+ f9 u8 a+ j! D5 ~& ^# K9 n
  307. /* Input:                                                                                                                                */& G  v6 u: e5 Y) ^6 L
  308. /*                None                                                                                                                        */0 k# S  d+ `/ ^5 b" E6 S" c5 W+ z
  309. /*                                                                                                                                                */6 v0 Q3 c$ ^  s
  310. /* Output:                                                                                                                                */. y  n1 F/ K( b2 _. {* C
  311. /*                WP                                                                                                                                */: J! Q! r/ p7 L" o% f- X4 U
  312. /************************************************************************/  f! x' N, ^9 `, a7 s, I! I/ I
  313. void WP_Low()
    * H$ M5 S0 n9 L! e: [1 O
  314. {
      B6 ~: Q! a% |9 {% F2 |
  315.         WP = 0;                                /* clear WP pin */+ l$ B/ S7 K: K) Y5 P  L
  316. }  {! A0 V0 a, `9 Q
  317. 4 f& v, F- W8 b7 c
  318. /************************************************************************/
    2 D. ]  V& g) [: Z( b' S4 _3 j8 Y
  319. /* PROCEDURE: UnWP()                                                                                                        */
    1 G; }( P/ t9 b' j; ~0 I
  320. /*                                                                                                                                                */( F( z$ R8 F5 k
  321. /* This procedure sets the WP pin to high.                                                                */5 Y) ~7 {0 A" {% B8 k
  322. /*                                                                                                                                                */9 j; H3 j/ a! @) |3 G+ G- e8 p
  323. /* Input:                                                                                                                                */3 b7 R% w% r  Y% ^
  324. /*                None                                                                                                                        */' G  _( F. Q* P( k/ M7 C4 s
  325. /*                                                                                                                                                */
    3 z0 W8 `/ X. m# ]* h% p' ], K
  326. /* Output:                                                                                                                                */) E% o( O/ {; b6 \
  327. /*                WP                                                                                                                                */" k: ]7 f/ X! r' A: q2 _9 E6 m( r
  328. /************************************************************************/" j2 F; J7 \2 C8 D, w. h
  329. void UnWP()+ ?0 |& ]1 Y; z. j( R
  330. {
    - c% ^6 d* d* f! x
  331.         WP = 1;                                /* set WP pin */+ v/ l% Q. A0 p1 c0 s; V9 c# I
  332. }1 r& n4 z8 P3 p& s$ ]. \6 J
  333. . M2 v+ G; J6 W2 N3 J
  334. /************************************************************************/# J3 J0 Y+ c- i, x
  335. /* PROCEDURE: Read_Status_Register                                                                                */( X/ t/ Y0 B* Y
  336. /*                                                                                                                                                */- |# G. F. |) @" c$ @$ R
  337. /* This procedure read the status register and returns the byte.                */
    ( s0 y4 M( }7 k6 |
  338. /*                                                                                                                                                */
    9 i2 b% ]( \, f! ]: t4 T
  339. /* Input:                                                                                                                                */, r/ g2 ~# U5 _, V0 L" T, }
  340. /*                None                                                                                                                        */& c/ Q$ _! ^( y& D
  341. /*                                                                                                                                                */
    , U9 i: w: U4 G: i- X' o! A
  342. /* Returns:                                                                                                                                */
    0 ?9 U4 p- a+ L# z) F
  343. /*                byte                                                                                                                        */, |' q# Y5 P1 e+ f# ?) ?' g
  344. /************************************************************************/6 M% w! Y2 i  h" ^! q
  345. unsigned char Read_Status_Register()1 L& {  r; w6 X0 e# C0 p
  346. {* g" Z+ L( e3 G1 g
  347.         unsigned char byte = 0;
    - B. O# d+ a  [! `. G5 ~0 J$ \) G
  348.         CE_Low();                                /* enable device */# ]3 N7 b0 O) u9 [( [  Y
  349.         Send_Byte(0x05);                /* send RDSR command */9 {. Z  X4 R; z! N) v
  350.         byte = Get_Byte();                /* receive byte */
    " c/ J, A: l1 H+ Z* y+ G) E# p
  351.         CE_High();                                /* disable device */2 T! e  a: B" Z! i* F
  352.         return byte;
    : E! i  i+ c, Z' w+ r
  353. }0 v' g% X5 A" ]- h

  354. 6 Q. v' v% G+ x4 j/ o0 w" v
  355. /************************************************************************/8 o2 e; p/ J9 B
  356. /* PROCEDURE: EWSR                                                                                                                */9 r% j1 e$ W- y/ ~7 Y7 }
  357. /*                                                                                                                                                */9 ]! W5 |) v+ G
  358. /* This procedure Enables Write Status Register.                                                  */
    - p9 ^3 T% V/ H/ ?5 m
  359. /*                                                                                                                                                */
    5 J4 w$ m0 q# y5 y1 P
  360. /* Input:                                                                                                                                */# F4 c0 j" J6 k) j! s
  361. /*                None                                                                                                                        */- X% [) X# P' R9 ]) P# i" A- A
  362. /*                                                                                                                                                */+ x* U) E* W6 K
  363. /* Returns:                                                                                                                                */% N- G5 |+ @+ p$ D. t
  364. /*                Nothing                                                                                                                        */
    & t; P  j8 J3 H% m/ g6 P
  365. /************************************************************************/; m4 U6 o: X  {$ _" A6 H8 s- W2 K
  366. void EWSR()! n; p$ p+ X. m% f& U  S
  367. {
    8 ?2 q$ `3 K5 G
  368.         CE_Low();                                /* enable device */
    / G  ]2 f1 W/ T6 d0 Q
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    1 s6 X; S8 v. z/ r4 o6 g
  370.         CE_High();                                /* disable device */
    6 f( Q/ C% c- m3 N$ P
  371. }( Q% ~4 Z3 z) f$ e
  372. : U6 v7 \1 b5 B& _" Y% `+ z) P1 I+ F
  373. /************************************************************************/
    # K+ x0 a# x- ^8 C9 \
  374. /* PROCEDURE: WRSR                                                                                                                */% h( p9 k3 L% P7 _" H6 O
  375. /*                                                                                                                                                */
    . l' C; N; b& N
  376. /* This procedure writes a byte to the Status Register.                                        */+ T% A4 I, ^& T2 _8 l% F
  377. /*                                                                                                                                                */7 o& u& t2 l& C4 k2 ]# H7 {  r' z
  378. /* Input:                                                                                                                                */2 E0 s7 f9 M, I) ], t
  379. /*                byte                                                                                                                        */
      ^5 A) X/ i$ E7 M. K
  380. /*                                                                                                                                                */
    + m0 b1 ?- G  I- e6 G  a
  381. /* Returns:                                                                                                                                */
    ; ?3 D, V. B, i0 _
  382. /*                Nothing                                                                                                                        */  L: m+ C8 e1 K& ^+ Q5 b
  383. /************************************************************************// Z) ^, S9 |- @  [7 \2 ?
  384. void WRSR(byte)8 {5 [2 r$ j7 j4 w; W; {
  385. {8 g5 ]- P2 O( r4 C
  386.         CE_Low();                                /* enable device */6 [0 g) J! W, _5 e
  387.         Send_Byte(0x01);                /* select write to status register */
    ' `' H: P* }1 E  E( n/ @6 W
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    . p; {' k! X5 d! P2 N
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */3 e: |2 f4 Q3 z, P5 w
  390.         CE_High();                                /* disable the device */
    ) _/ n; Q8 E) |; J% ]( x3 L% J: {0 r
  391. }7 G# e+ r' J( U& F8 N

  392. 7 V9 ^0 c; L0 z1 c" O$ B3 ~3 ~; n* \
  393. /************************************************************************/
    , K3 y- c0 C2 B* G3 H
  394. /* PROCEDURE: WREN                                                                                                                */
    ! D9 Y8 N- i; X# d% ]# B
  395. /*                                                                                                                                                */% f" ]! F4 x% w
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    8 h4 i4 F: `( M
  397. /* to Enables Write Status Register.                                                                        */
    ; I+ i1 J& ?' r0 z' }5 r
  398. /*                                                                                                                                                */& z3 y( h. s; Z- S7 A6 ^: [# Q
  399. /* Input:                                                                                                                                */. T" r% o; B- C& K; `. d+ s* }
  400. /*                None                                                                                                                        */
    9 u. o6 H4 O3 e: A/ q
  401. /*                                                                                                                                                */2 @+ A% [+ X5 B0 `' a7 X; C
  402. /* Returns:                                                                                                                                */
    - A( h; d" R7 A
  403. /*                Nothing                                                                                                                        */
    ) ?7 b* T  `5 n' x, a
  404. /************************************************************************/* a/ u' Z; T  n
  405. void WREN()3 T( @  P& U% o  t: {
  406. {0 U8 v  Y2 A9 H) r5 c3 T7 \
  407.         CE_Low();                                /* enable device */
    $ Y( f+ a- a, E  I% B
  408.         Send_Byte(0x06);                /* send WREN command */
    3 w  \# I% G7 Q1 I1 `
  409.         CE_High();                                /* disable device */
    / G1 w( \/ I. C
  410. }
    * Y2 y+ n+ b7 P0 W7 S0 Q8 [

  411. # [1 Q0 v7 S3 K+ D& B4 j
  412. /************************************************************************/0 g( z6 p5 @1 R' q" u3 U8 r& W
  413. /* PROCEDURE: WRDI                                                                                                                *// }: a# c3 o- ^- a. [( A) D5 R' G
  414. /*                                                                                                                                                */8 T& B2 a3 H2 O" v, a- X
  415. /* This procedure disables the Write Enable Latch.                                                */1 {* ?1 U9 ^( Y) p; q! ~
  416. /*                                                                                                                                                */
    # A. [; `* |# k6 l+ L' U; J
  417. /* Input:                                                                                                                                */% `0 R2 F' f* {9 [6 p- o' P
  418. /*                None                                                                                                                        */
    - x6 B* c; ]+ \' o6 c+ d& A  E+ s
  419. /*                                                                                                                                                */
    0 O) b* E, t2 f! P. {' P% y# y
  420. /* Returns:                                                                                                                                */7 l$ N; A5 T& {/ M& a+ V
  421. /*                Nothing                                                                                                                        */! W2 j5 ~% S; N4 G$ w: Y
  422. /************************************************************************/2 k  Z  o8 V  q6 n4 A+ x! B8 j* x
  423. void WRDI()
    ! C4 ]6 b/ Q' {2 y% X* a% c
  424. {
    ) Z* F( _3 B9 w/ ]5 b, U' c1 D) v
  425.         CE_Low();                                /* enable device */, h. X  n5 N1 i5 b, E9 A- Y+ J
  426.         Send_Byte(0x04);                /* send WRDI command */
    5 Y7 k, [1 j8 l5 L3 M8 v4 E: W
  427.         CE_High();                                /* disable device */
    3 ~% ^+ |) g: Q- R
  428. }, T$ l0 K4 l! r% G; p: _7 l, H

  429. 8 s& S& }5 w* B- d" F+ F
  430. /************************************************************************/
    ) v4 z) O3 [( E( w3 T1 o- V
  431. /* PROCEDURE: EBSY                                                                                                                */$ l7 N) S0 t% d& l: h$ E, n
  432. /*                                                                                                                                                */
    % T; t; I5 U# k) Q7 {
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    7 ], u/ N% J8 K) j9 I. U0 O
  434. /* programming.                                                                                                                        */$ X8 d8 G- {' @0 U% t' m! f. a
  435. /*                                                                                                                                                */
    % J1 Q9 ~- L; d
  436. /* Input:                                                                                                                                */
    , q5 _- u( ^1 h& G
  437. /*                None                                                                                                                        */4 g: y8 @4 A3 A" f1 Z
  438. /*                                                                                                                                                */. M' A- j7 m+ z& {
  439. /* Returns:                                                                                                                                */7 f3 `9 ~' x  V$ f7 L
  440. /*                Nothing                                                                                                                        */
    0 \6 @% d1 g& B' O4 {  f; w
  441. /************************************************************************/; _- u. x, C, m0 c: Q. F
  442. void EBSY()
    4 f4 y+ r0 `* T3 g, A8 _7 y. Q
  443. {0 h2 X6 _( o! Y& j4 K* w- z$ l
  444.         CE_Low();                                /* enable device */
    3 H2 c- D( y1 p, O1 R* P" O
  445.         Send_Byte(0x70);                /* send EBSY command */$ ]$ F1 L. Y5 f
  446.         CE_High();                                /* disable device */
    8 d4 U4 u2 j' j: r% x* ^
  447. }5 W3 y1 K- D# l) {) y0 g. V/ \3 q8 ]( j

  448. : w+ h0 R# ]2 @' D, J- _
  449. /************************************************************************/& Y" A$ L& f# `8 \
  450. /* PROCEDURE: DBSY                                                                                                                */
    - o+ K4 V" z: q3 e; O
  451. /*                                                                                                                                                */
    & g7 m) l" ~$ h3 E, l2 x5 E
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */! a" y5 k( Z# ^
  453. /* programming.                                                                                                                        */
    % K5 h: r+ p3 z6 }, W/ K
  454. /*                                                                                                                                                */
    ) e6 L! V1 A* y, Y5 [) o
  455. /* Input:                                                                                                                                */
    5 N2 H5 |2 N* @
  456. /*                None                                                                                                                        */: c, G4 s: q* N( m' V# C: d8 |) W
  457. /*                                                                                                                                                */' _7 Z* L* O+ ~8 D$ {% p4 `
  458. /* Returns:                                                                                                                                */
    ; P5 {8 ^5 U. G7 O' E
  459. /*                Nothing                                                                                                                        */
    2 F2 L6 M  e0 v& F) ]% v. F4 @
  460. /************************************************************************/
    2 P; d& L) @6 [/ E% m* ^
  461. void DBSY()
    ( L. G2 _5 ^0 Q' Y0 R
  462. {9 E# `  P8 L, }' @: `
  463.         CE_Low();                                /* enable device */
    ' Y/ h. F: c8 h: G" r3 i
  464.         Send_Byte(0x80);                /* send DBSY command */
    ' u" k$ ]6 i, x' l# f$ r
  465.         CE_High();                                /* disable device */
    3 |0 t9 ^5 L4 ^8 f+ X' Z) N
  466. }
    + I" t4 R+ H( O" a0 \$ r6 K3 u* p& M) M

  467. 6 [, W; a% `/ F
  468. /************************************************************************/: m8 J/ z' ~" P' \. o+ X
  469. /* PROCEDURE: Read_ID                                                                                                        */+ D7 L9 x! I& y& H0 {; v7 z
  470. /*                                                                                                                                                */1 Z' |. \! x" m* z
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    8 o9 y1 t9 }' |! h' m1 |
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */# h. \! X; S4 v# ~, F2 C
  473. /* It is up to the user to give the last byte ID_addr to determine      */7 o+ `$ W# F0 ^4 o; [9 c: ~9 [
  474. /* whether the device outputs manufacturer's ID first, or device ID         */$ q! F3 ^" d! k/ W# i: r0 c
  475. /* first.  Please see the product datasheet for details.  Returns ID in */; F# `; b; Z4 K& I8 o7 T
  476. /* variable byte.                                                                                                                */
    1 _- k+ f) x3 E7 ?! A
  477. /*                                                                                                                                                */
    7 |& X$ K3 a4 J8 @
  478. /* Input:                                                                                                                                */
    - x( f( R& S3 N: I& a
  479. /*                ID_addr                                                                                                                        */3 a4 i; Y3 M8 I1 g
  480. /*                                                                                                                                                */
    $ |4 ?( X+ H) J7 @
  481. /* Returns:                                                                                                                                */+ C1 q4 |* h% F6 r3 N" H8 X/ z
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    % p; W8 K4 L( B3 G4 W
  483. /*                                                                                                                                                */
    # E3 h: h, @5 B" F5 f! _1 T* @5 J; T
  484. /************************************************************************/8 |% P6 C  `$ J
  485. unsigned char Read_ID(ID_addr)
    * M3 Y- n% ?" Y- n
  486. {7 c2 W' D( ?7 U+ @, b, h# y
  487.         unsigned char byte;7 f; Y# `  ~8 O( D* x! f
  488.         CE_Low();                                /* enable device */
      l* ^8 f" D8 E( l; B6 }
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    * s9 H; l: U" L2 c) c
  490.     Send_Byte(0x00);                /* send address */
    - l4 O7 N% U# F" Q* O  L6 M
  491.         Send_Byte(0x00);                /* send address */; H$ p& Y) ~0 H8 F, F6 L
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */3 p/ W6 ~6 |8 C! x$ a) F
  493.         byte = Get_Byte();                /* receive byte */
    ) q; E' U1 E& r% A
  494.         CE_High();                                /* disable device */* ?- R5 Y5 P: ^$ @6 a# G! A
  495.         return byte;
    ) g) X( l$ \- m/ c; u% z. \
  496. }
    , e9 W6 _, x3 ?

  497. 8 S7 k6 y6 H  C5 \+ _' K
  498. /************************************************************************/
    6 Y! N, I4 I, M4 d
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    ( m% M2 p" k( I/ z% O
  500. /*                                                                                                                                                */
    0 w$ [" t3 i- `( |7 g8 T
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    - Q5 ?+ \1 X% z4 m8 {4 O
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */- B- Q( |9 z. p. n9 O% d; V# e' D$ m
  503. /* Please see the product datasheet for details.                                                  */- N4 U3 w8 a, _0 |$ D
  504. /*                                                                                                                                                */$ Y+ F. G4 u/ W0 B
  505. /* Input:                                                                                                                                */! `  h1 `$ @: s
  506. /*                None                                                                                                                        */
    # i, t* ^3 O7 k% U( O
  507. /*                                                                                                                                                */
    ) s; X% m3 E- f3 X$ [
  508. /* Returns:                                                                                                                                */
    # F  p: ~# `( Z# L8 p6 u
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */; U/ T  p3 |8 G0 {6 {) \
  510. /*                 and Device ID (8Eh)                                                                                        */- T; C" \8 |: Y2 L# J6 C, Q
  511. /*                                                                                                                                                */
    / G) Y7 b/ n( {3 o: Q
  512. /************************************************************************// E, b* m" W& X! P# R+ X
  513. unsigned long Jedec_ID_Read() 3 V" _# c; j3 q6 {
  514. {# }* }* ~3 g$ t% E5 u
  515.         unsigned long temp;# J, T2 Z0 z& D4 ^+ `
  516.         / g) B7 m: m: j: f  ^# |
  517.         temp = 0;
    0 l4 i) Z* E( A, e- L: Y

  518. - E, V9 B) j; o% `- {, E
  519.         CE_Low();                                        /* enable device */
    " R& t5 ^/ S/ y  {. {% b
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    , V% _3 t8 z9 }3 P- U( _4 \3 b
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    + g% z6 y; r6 d; }
  522.         temp = (temp | Get_Byte()) << 8;       
    1 q* C0 U# J8 E- L
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    " X5 a1 u2 c# H9 g$ p! u
  524.         CE_High();                                                        /* disable device */
      c" n7 _; x) l- x

  525. ! S: f: j+ ]0 ?7 @" z& Z5 c/ ?
  526.         return temp;
    : @. J6 V" H& Z9 D2 h" J3 Y0 I3 i
  527. }
    ! A3 Z) m0 x( e* b2 }. N

  528. : s" ^/ I5 ^6 S0 C
  529. /************************************************************************/
    2 q* u1 p+ p1 g6 \# Y# F
  530. /* PROCEDURE:        Read                                                                                                        */+ a' a+ w0 |, z% S* {: G6 c
  531. /*                                                                                                                                                */                5 R! c9 G+ q8 n" q+ ~
  532. /* This procedure reads one address of the device.  It will return the         */
    1 W6 v  A0 c" Y$ e
  533. /* byte read in variable byte.                                                                                        */$ f& n' d& V. I9 U; g/ d3 E+ E
  534. /*                                                                                                                                                *// ^# Y6 C5 l+ Z( g' M8 i
  535. /*                                                                                                                                                */
    3 B3 K. x' B0 Z0 Y6 `  ]
  536. /*                                                                                                                                                */
    $ Z$ m$ q" b% L3 W4 o
  537. /* Input:                                                                                                                                */1 A+ m+ d7 G' }
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */( m: n; n: h, Y( b4 \
  539. /*                                                                                                                                      */' O' k; B; r/ `" c* d* r+ T2 `7 y! _
  540. /*                                                                                                                                                */" s4 O8 s& ^" X
  541. /* Returns:                                                                                                                                */  o; N0 t) H/ w8 e+ j
  542. /*                byte                                                                                                                        */
    7 ]4 Z* k5 x- ]
  543. /*                                                                                                                                                */: {' S% i& _  n  ]4 P/ V! W6 o1 o& X7 k
  544. /************************************************************************/
    2 Y0 ]3 f3 a& o5 v* r
  545. unsigned char Read(unsigned long Dst)
    % b/ i5 d- J% e6 m1 ]! \
  546. {3 l1 b- z8 I- J/ K4 n+ U3 E7 M& X
  547.         unsigned char byte = 0;        0 n% R3 k$ E! \& Q

  548. 5 g" J$ s  q  A( {
  549.         CE_Low();                                /* enable device */$ j6 N$ h- N- a5 w- B. S" V  m
  550.         Send_Byte(0x03);                 /* read command */
    & B9 h" h1 K: {! a
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */# d& D0 T0 k* |) l/ E# h
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));/ F7 }( a$ X* [9 H, r
  553.         Send_Byte(Dst & 0xFF);7 ]8 I0 Z7 o2 X1 u5 J4 G3 \. o( O' C+ Z
  554.         byte = Get_Byte();
    ! |5 c+ C# \8 Z  s' D" \
  555.         CE_High();                                /* disable device */  N3 U! @3 c3 r% W
  556.         return byte;                        /* return one byte read */# u3 W: y4 T( M5 l' m2 t
  557. }; ]" A+ n& s9 F: m9 S7 L! _1 a
  558. % W+ e1 E! v2 ^- o: K1 ~0 Z
  559. /************************************************************************/
    * p8 Z9 s0 t/ T. n) M
  560. /* PROCEDURE:        Read_Cont                                                                                                */; b  m# a% r2 A$ v9 ^
  561. /*                                                                                                                                                */               
    , r9 c7 ?* X" z, ?% f9 V6 i) Q
  562. /* This procedure reads multiple addresses of the device and stores                */# ?1 {7 n/ J: W, O+ q
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/+ P2 u7 I1 ~0 ]$ g, b
  564. /*                                                                                                                                                */5 u9 H- x4 B5 y' N: [% m
  565. /* Input:                                                                                                                                */
    2 {) j/ u2 P* b) @% y3 x( `
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    . \3 j+ [1 k' T- |
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */% |! n2 k: R+ c* z, ?; l
  568. /*                                                                                                                                                */
    - l2 D  q5 Y) ]% O
  569. /* Returns:                                                                                                                                */' D! O6 N8 T+ G' f
  570. /*                Nothing                                                                                                                        */
    1 g# m9 _3 G% {% t7 F0 G
  571. /*                                                                                                                                                */% _" e6 a7 f5 L! P3 ]  G0 @5 V
  572. /************************************************************************/
    ; j, R- N- C% e/ X
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)7 Y5 f6 p7 O" g
  574. {/ K# K8 r" B1 l
  575.         unsigned long i = 0;7 r) J0 v4 [0 T6 V
  576.         CE_Low();                                        /* enable device */
    4 \+ Q7 \$ A9 u* R! Z4 U$ C2 C4 o
  577.         Send_Byte(0x03);                         /* read command */
    7 z8 Q& v- c& m
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */5 }) [# Q8 I) j- k
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));% w+ F0 D8 }' M* p9 n. S, m$ z5 e
  580.         Send_Byte(Dst & 0xFF);
    6 [. l* s8 Z1 V) T' j) r
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    * v9 l0 _$ p" S6 q* @. p; D9 V, J; Z
  582.         {2 X9 p( t$ X% p9 z  H4 J
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    & m& Q) T! C: U% b6 `
  584.         }
    - W, n. A9 z" G: p/ @, p
  585.         CE_High();                                        /* disable device */9 E9 W3 S* e$ Z' q8 X7 L

  586. , }) u& k* H* W( l3 F
  587. }5 k- J8 ]/ D* ]/ P
  588. . `; E" Y) u$ g9 m# M
  589. /************************************************************************/
    8 Q+ i: @& \! E/ C5 ?  G# E
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */' _7 N. C1 ?2 u& q2 I' T" k* s
  591. /*                                                                                                                                                */                9 s4 e* N5 r1 A5 t( `
  592. /* This procedure reads one address of the device.  It will return the         */
    # O+ o' i1 f% ]& T  R
  593. /* byte read in variable byte.                                                                                        */
    # d% c9 \7 S& t: w( r6 Y! D
  594. /*                                                                                                                                                */
    6 g- @0 n9 X  n, J- _; |9 p
  595. /*                                                                                                                                                */* M+ }' Q3 \8 Q
  596. /*                                                                                                                                                */5 ]2 v  C! G! I. q
  597. /* Input:                                                                                                                                */
    ! u4 F/ O$ x6 ^8 V. J; c) |
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */) a' I9 ^+ r% W* O3 @$ \. ^, Y! U. W
  599. /*                                                                                                                                      */& {$ c- R: D% S
  600. /*                                                                                                                                                */& J  K. N; M- f8 p- d
  601. /* Returns:                                                                                                                                */) G1 E+ ]) n9 a) P  q
  602. /*                byte                                                                                                                        */
    " m; b" `$ W5 }7 \7 a  N2 i! d
  603. /*                                                                                                                                                */
    . p! B9 M# D/ ^$ o/ O$ j6 ]& m
  604. /************************************************************************/6 |! R& P4 i( i! J
  605. unsigned char HighSpeed_Read(unsigned long Dst) $ Z# F" \6 l: v4 T1 D* W& M
  606. {3 q! E1 v2 h5 V% a# R* G
  607.         unsigned char byte = 0;        + E( _0 H! x. Y$ i1 M6 X+ f

  608. 8 k& o6 ]* Q+ J4 g" j2 ~! \3 _
  609.         CE_Low();                                /* enable device */4 w& e" Q8 {" X$ b' u
  610.         Send_Byte(0x0B);                 /* read command */  E6 v) L5 p, I% c. V6 t' B
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    9 r' n" ^1 ?1 T4 z; l9 I3 @& {: ^/ [
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));% a1 A$ q' u7 y2 b) p
  613.         Send_Byte(Dst & 0xFF);/ N( e' S& K' C2 W4 e$ z
  614.         Send_Byte(0xFF);                /*dummy byte*/" [1 g) @8 o% p% _! J: X; Y
  615.         byte = Get_Byte();( F/ `. l2 H' ?  j, o& L
  616.         CE_High();                                /* disable device */
    + q( ]- A2 O! p7 M6 [& Q2 {/ P
  617.         return byte;                        /* return one byte read */  e7 d7 z. A$ |, K
  618. }
    - n7 H+ V, Z4 s
  619. 3 p0 X7 A' s. N- r7 O3 N! I
  620. /************************************************************************/
    6 Z8 T1 |- w: a: a" G% J0 ]
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */" A. K6 `' Q$ i# Y, }
  622. /*                                                                                                                                                */               
    - A* h" W3 ?+ q" Q8 A6 v/ z
  623. /* This procedure reads multiple addresses of the device and stores                */4 m. X" l1 J) \  B  ?6 Z
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/+ H* Y4 V0 B. }+ j* R5 L
  625. /*                                                                                                                                                */2 F9 p  O7 [9 n" @
  626. /* Input:                                                                                                                                */
    4 M9 V+ h9 w( E/ G* \
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */  t+ Z6 J) v" Y8 C
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */8 @0 |$ a/ \% k' o+ R$ T7 L: C6 c
  629. /*                                                                                                                                                */
    6 X& s/ [4 r/ @
  630. /* Returns:                                                                                                                                */
    ( f2 Y; f$ N- Z) L
  631. /*                Nothing                                                                                                                        */1 m6 \- j6 x# x) o, N
  632. /*                                                                                                                                                */
    $ }) {; q6 `8 R( y+ T) V1 C4 P
  633. /************************************************************************/
    2 b: M. G* D: d
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    & d1 ]: K0 V& e0 D* F
  635. {3 d. ~. `+ ]1 `9 y3 x/ p
  636.         unsigned long i = 0;
    ' `9 z% }( d  {' ^& Q+ {
  637.         CE_Low();                                        /* enable device */
      o# J2 k) @  X$ s1 u
  638.         Send_Byte(0x0B);                         /* read command */7 W8 H4 p0 D0 A8 y" E; m7 K, m3 R( R
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ' e: F6 D: Z. Q* c
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));& }7 o' }6 f/ e2 `
  641.         Send_Byte(Dst & 0xFF);# g0 v9 `* Q& l6 _7 h! h; }
  642.         Send_Byte(0xFF);                        /*dummy byte*/1 `7 p1 Z1 {: }' D1 I/ j9 W1 y% N; ], |
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    . S6 E- Z+ {2 E; V
  644.         {7 I! Q+ F- `, |5 Z
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */9 `6 `1 c$ ]7 J
  646.         }
    3 r$ k# M% g8 i* g
  647.         CE_High();                                /* disable device */
    $ F5 w# W9 K2 _+ w
  648. }  u6 N# c, o0 e

  649.   j1 B$ I8 r% J
  650. /************************************************************************/% E. G# J6 D' m2 G2 u  @6 \! m
  651. /* PROCEDURE:        Byte_Program                                                                                        */% i* S7 [( n5 r% Q" h: Z1 @
  652. /*                                                                                                                                                */
    # ]; {6 y4 c' ^
  653. /* This procedure programs one address of the device.                                        */& b7 U  Y' W, Z7 X2 |. D
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    " z! Q( I2 ^& S5 J" |( f$ m
  655. /* block protected.                                                                                                                */* n# v3 }/ Q8 q
  656. /*                                                                                                                                                */. [6 w3 e& D% T$ t  M7 J8 U. V* z
  657. /*                                                                                                                                                */
    ! q# H% Y6 `$ }8 i' D5 P. [; Q
  658. /*                                                                                                                                                */
    ) C% `2 P1 d/ L$ w) i/ a
  659. /* Input:                                                                                                                                */
    3 K, f: \# h) ]
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    / V/ s% Q7 j* o. v- Q
  661. /*                byte:                byte to be programmed                                                                */' K( B+ \' x, W/ m( Q
  662. /*                                                                                                                                      */$ W8 r) C& \4 N/ m/ o
  663. /*                                                                                                                                                */
    0 t2 t: g, O# c  z
  664. /* Returns:                                                                                                                                */
    ( R2 H6 j' Q4 y0 k
  665. /*                Nothing                                                                                                                        */
    1 B; J, X5 @# q: ]0 A! l; r
  666. /*                                                                                                                                                */8 o  B8 H: W# w* j+ [
  667. /************************************************************************/  o6 `, N1 ~: K
  668. void Byte_Program(unsigned long Dst, unsigned char byte)" c% k% d8 m  A- i
  669. {
    * G# i) @! Z$ Z2 o% O0 Z1 M# B
  670.         CE_Low();                                        /* enable device *// H+ z0 V9 i0 r# m
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    7 C8 J6 {# W' m* v- T
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    : `9 i% w! R; Q2 P. ]7 F
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));8 q/ n. ?( l4 i! ?- d1 C0 ?" _, P
  674.         Send_Byte(Dst & 0xFF);
    & [0 O% x- G+ u) }, x+ c2 Q
  675.         Send_Byte(byte);                        /* send byte to be programmed */9 @$ G2 m3 _- I/ m6 k+ `
  676.         CE_High();                                        /* disable device */
    $ M9 L& l3 |0 D9 j( {
  677. }
    / y5 X5 E% ~2 E( Q* T

  678. : c9 Y5 @3 J" z8 ]  g, l* V
  679. /************************************************************************/
    & r# y0 |' y+ F; e/ e! l( b; r4 y
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    , C7 {( u' Y& a. `4 |: K
  681. /*                                                                                                                                                */
    1 D& H0 |5 e' `* t
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/4 S2 V/ w( P- Q! r% Y% r9 n* ?* D
  683. /* the device:  1st data byte will be programmed into the initial                 */3 D' O5 ?2 s  G1 X0 u4 \
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    - S  t7 T4 j+ D1 a
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */2 R* M2 A0 x: p+ H& M. F
  686. /* is used to to start the AAI process.  It should be followed by                 */
    - r3 Y! R2 \! U1 a5 m. E3 z
  687. /* Auto_Add_IncB.                                                                                                                */
    0 ^0 z/ p8 s: ^9 T/ e! X8 c
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    8 E- C8 W! F$ P$ y: Y4 y# O; F# ]
  689. /*                                block protected.                                                                                */
    8 {, G, v* W+ @: y( G1 y/ w
  690. /*                                                                                                                                                */
    0 Q% V9 n: _) `- |* w5 v/ s
  691. /*                                                                                                                                                */
    ; q/ t5 s# X; ?* x$ V% w/ W: c+ a
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    ' E* M- l4 \. e
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    5 V2 v$ J# Y6 ^( Z4 Q8 k
  694. /*         unless AAI is programming the last address or last address of                */
    : G1 v3 a' i/ @; x% J
  695. /*          unprotected block, which automatically exits AAI mode.                                */8 L" j8 w7 M- B
  696. /*                                                                                                                                                */+ B5 I: M* S! [5 Y! h* E
  697. /* Input:                                                                                                                                */
    2 g% ?9 l: V/ ^9 [$ K- `  B# j
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */9 f2 _9 {, p' u
  699. /*                byte1:                1st byte to be programmed                                                        */* k/ p2 `  M, S' Y$ ]  V3 u8 M5 z
  700. /*      byte1:                2nd byte to be programmed                                                        */3 ^5 q$ z/ A' d6 i+ m+ L3 @, U! N
  701. /*                                                                                                                                                */
    3 P4 @$ {  ~0 d7 g0 ~
  702. /* Returns:                                                                                                                                */
    % J1 V3 S; j2 K  V: [' E5 L$ T
  703. /*                Nothing                                                                                                                        */
    # u  e) G, P! ~8 W0 z
  704. /*                                                                                                                                                */+ A6 H$ r- X2 k: e; U! Q' u, H
  705. /************************************************************************/- e' h+ d# u0 m" H1 o
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    ! O- L& @& s% j3 ]: y* w
  707. {
    4 ?) B# P, L& n
  708.         CE_Low();                                        /* enable device */
    9 q3 @$ E# ^( C5 j: o/ u% C
  709.         Send_Byte(0xAD);                        /* send AAI command */
    5 Y" S8 v4 j: Z" c
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */1 K, h  N: z0 p: }
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - U, Z1 N: m0 c1 W  h# e4 m: W% e6 w
  712.         Send_Byte(Dst & 0xFF);+ F9 q. u+ B& ]( c" l9 c7 S
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    6 d+ T; @: Q8 }* [! g+ t
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    . X  h; n+ {! |5 j' z* D  k
  715.         CE_High();                                        /* disable device */
    ) x  R  ?) b0 H3 u2 J/ C
  716. }* ?2 b- |; I% v3 o0 Z. Z
  717. ; s+ _5 C2 @# ^; u4 H9 _
  718. /************************************************************************/* `' S0 T0 H6 y% i! A8 U: F
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */$ |  U( F1 F. f  X5 C$ F: ^9 L7 Z2 R9 I
  720. /*                                                                                                                                                */2 l8 |! j3 X1 x" q- V4 x
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/- F  {$ I2 F8 w
  722. /* the device:  1st data byte will be programmed into the initial                 */
    9 G4 }1 w- U- z6 y
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    + G2 S4 m2 [! \/ ]% \6 [/ k
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    2 p  j  U; V6 U" [* t. j
  725. /* is used after Auto_Address_IncA.                                                                                */
      D: z, u; B4 D9 P& S1 j. ?) h
  726. /* Assumption:  Address being programmed is already erased and is NOT        */, O$ g- H; v4 K+ P8 N2 N8 L
  727. /*                                block protected.                                                                                */
      e3 ]8 ]( T4 }* ]4 u
  728. /*                                                                                                                                                */4 |1 n4 V% L8 F3 V! k" b8 K; I
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */$ ~2 z3 z! t) P/ X+ O4 c, h
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    2 P+ B1 w4 `  \+ J" p
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */3 S$ }2 k/ F. a. ~7 m0 m  F" h
  732. /*          to exit AAI mode unless AAI is programming the last address or                */: o) i4 M) M0 S4 f5 r- C
  733. /*         last address of unprotected block, which automatically exits                 */* R  v4 M( Y8 U9 h$ S4 u: T. `+ `
  734. /*         AAI mode.                                                                                                                        *// C) W  F9 r! A6 k+ q5 R6 D, d6 s
  735. /*                                                                                                                                                */$ F! y9 P' w. ]/ B6 h. x8 v; O8 T( R) r
  736. /* Input:                                                                                                                                */* d7 Z' K" ]( Q' z: O+ }# x' n
  737. /*                                                                                                                                                */& B* P6 o- s$ Q2 P
  738. /*                byte1:                1st byte to be programmed                                                        */
    / q. \6 T5 c/ j7 f% N3 J8 U7 Y
  739. /*                byte2:                2nd byte to be programmed                                                        */
    + _4 S5 m8 n. V/ t& i! s9 l
  740. /*                                                                                                                                      */' |+ F( u8 ~5 g& e* w
  741. /*                                                                                                                                                */1 c: x" Q6 I" n/ L7 Z
  742. /* Returns:                                                                                                                                */: E( I2 m& g' X! T# J- `1 d
  743. /*                Nothing                                                                                                                        *// e' L- X2 X; q$ G
  744. /*                                                                                                                                                */
    6 ^. j8 M7 ?1 x, L7 p# l2 \2 j
  745. /************************************************************************/7 f+ @( Z% I* f
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    8 {1 i  b# U  b. D
  747. {
    2 ~7 m  w7 v/ M8 _; e; N
  748.         CE_Low();                                        /* enable device */6 w: r9 h2 {( k  ]
  749.         Send_Byte(0xAD);                        /* send AAI command *// ~- a, W. U/ p# X6 D9 c
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */4 `% w& B2 ^$ H& T/ T
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */" H8 a/ ^* P$ ^% w
  752.         CE_High();                                        /* disable device */
    8 E9 K1 C. B' c2 c, S( h! F7 {
  753. }
    3 l% N1 g; b3 x4 n, Q9 Y
  754. : L0 T. l7 t9 _* v  [, [: _
  755. /************************************************************************/
    ; v4 n; T5 `  }3 l( }6 q; C( H8 R
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    3 V4 u* V+ l3 e  r: }8 [
  757. /*                                                                                                                                                */
    6 K: C5 L3 `0 {  d' b
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    ) ?% R. _6 n" Y, w. K1 Z. U
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    & g) A2 O+ i: C) @- C6 i8 g
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    7 l- N0 M1 D3 U; X$ i
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    ( o, B) b, n( `% r) ?; B
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    8 ?  M4 d# ~. V8 ]4 E9 i* ?
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    ! v# U9 t% ^% b: T5 e
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    ; |+ a0 H6 M  e1 l- b$ S! B
  765. /* Assumption:  Address being programmed is already erased and is NOT        */1 C  @* I$ M3 C
  766. /*                                block protected.                                                                                */9 s0 n, E0 j6 a% ^2 [
  767. /*                                                                                                                                                */3 ?! U8 Z1 t; @
  768. /*                                                                                                                                                */
    ( N$ I0 t- c, }# e# Z* b1 X. d2 h* f
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */% q) s; ^  G  V2 K8 p) p4 n' S
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */6 s' |5 \  ]2 v$ k! ]& y; u3 q
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */+ g, a( n' r! u% Q( C5 q
  772. /*          to exit AAI mode unless AAI is programming the last address or                */( n, M9 i  P9 m. p, D
  773. /*         last address of unprotected block, which automatically exits                 */) p  R* @! w- e5 o* P
  774. /*         AAI mode.                                                                                                                        */" Y; j& M" @, G& X
  775. /*                                                                                                                                                */
    + M; R$ @3 i3 i7 o. y% b
  776. /* Input:                                                                                                                                */$ E# S* m# _: V
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */" A0 Y+ t: T4 t# F
  778. /*                byte1:                1st byte to be programmed                                                        */' j. b' `6 P1 B9 M# g# K
  779. /*      byte1:                2nd byte to be programmed                                                        */
    ; c) m/ C! ~% q# l& n) v
  780. /*                                                                                                                                                */
    6 l  b! Y+ p$ q) \! ?9 e
  781. /* Returns:                                                                                                                                */5 N) a# h9 d" w. G# W) u
  782. /*                Nothing                                                                                                                        */4 U1 d, D  B8 F
  783. /*                                                                                                                                                */% P# X( z: h- Z9 Z4 E
  784. /************************************************************************/3 Q5 |+ F: P0 d  J, [
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)# ^4 z2 K8 G" ]9 T% r
  786. {  g- |* R' \* R7 C, l
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        0 M# |: r: v8 x8 X4 U
  788. # ^$ r3 S& c3 i# H/ o  _; E
  789.         CE_Low();                                        /* enable device */
    & r5 Q" ]8 A" |' }
  790.         Send_Byte(0xAD);                        /* send AAI command */
    / f8 r. K- W  z1 t! ?* p% F
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */7 H1 `; z& i7 ~- ^' K
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ) m  o# L0 X1 F8 V2 ~2 r* N% p( v6 p
  793.         Send_Byte(Dst & 0xFF);
    # x. B7 k" t# U( D' w3 ^
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    ( Z. U' @% Z9 b: h4 |/ h
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */2 c+ ~, V1 h% q  k$ d) `
  796.         CE_High();                                        /* disable device */9 q/ M% q$ q0 w; h
  797.         3 v, Q2 G* f7 s! d; R$ Q% O
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    & T) X* Y' B" X& r" b

  799. 5 Z. {+ w+ Y4 S9 g& C! J
  800. }
    ( R( r2 s. T& [
  801. 6 t$ i; q  x4 R% y  h. H4 @# G
  802. /************************************************************************/9 C4 v; }3 A) P' R9 T1 z
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */" z; f8 z% ?& Y6 \  X$ |
  804. /*                                                                                                                                                */+ F( E3 i' y2 o5 Z: \
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    + t7 B- u. r) B: `0 A( N) W
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */  B: X' P8 {$ _4 Z9 ?4 N
  807. /* AAI programmming is completed.  It programs consecutive addresses of */: K: S& \9 _( e) n6 {# K! S
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    % \2 X6 G' V0 o, |' S- @* [
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */+ t+ B/ K1 r8 \
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */+ \0 i3 O8 z3 |( z
  811. /* used after Auto_Address_IncA.                                                                                */) n# K+ R* c  i5 \% v. R; o
  812. /* Assumption:  Address being programmed is already erased and is NOT        */. p! w+ w2 _$ {1 i
  813. /*                                block protected.                                                                                */  {' X  l9 u: _. H; w  y
  814. /*                                                                                                                                                */
    4 W  I* c9 ~4 G, N0 M: N; u1 q
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    # R/ i/ O* \: B( n, d# [
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    , r: j# |% b3 z5 a( {
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    ! M1 B4 T' T8 B. ]' V$ m
  818. /*          to exit AAI mode unless AAI is programming the last address or                */4 g9 x9 j/ D. r: w
  819. /*         last address of unprotected block, which automatically exits                 */
    + ?) `8 G  \/ \0 W' y
  820. /*         AAI mode.                                                                                                                        */2 n/ `9 H. o; n2 G7 `
  821. /*                                                                                                                                                */
    1 l9 c/ y% u3 w1 C* t$ h7 O
  822. /* Input:                                                                                                                                */* y+ o$ c* ~9 h- s
  823. /*                                                                                                                                                */
    . a( M% [  }# Y
  824. /*                byte1:                1st byte to be programmed                                                        */
    8 G+ ^( M0 t) V, W' P6 |
  825. /*                byte2:                2nd byte to be programmed                                                        */
    6 L3 |: p. S/ s+ E. n/ I
  826. /*                                                                                                                                      */
    3 V" Q* |% c0 a$ [) u
  827. /*                                                                                                                                                */- p) r- t/ J, x5 T' Q) }
  828. /* Returns:                                                                                                                                */3 l) n& `3 l( e0 ^+ R7 x* b
  829. /*                Nothing                                                                                                                        */3 A" K5 @& R) f$ |* ~
  830. /*                                                                                                                                                */
    & a% c- f$ z+ y: ?& Y+ U
  831. /************************************************************************/
    0 ^; T  m  Z" {. l! P
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    ) `  [6 I. ^" U  i* M; |5 \
  833. {
    ' C/ v; _) f) e+ R- L3 u) _
  834.         CE_Low();                                /* enable device */# ~  \+ u/ [* D" G2 ~( b
  835.         Send_Byte(0xAD);                /* send AAI command */; `3 \1 M+ \( S4 h+ {
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */$ n( d) v! a6 i- N/ I  }1 e
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */! A- V$ i( _8 `  P
  838.         CE_High();                                /* disable device */
    3 \- j* }2 v/ ]5 w* {

  839. 8 _+ _; c6 ?* N+ z1 `5 n* w# W
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    " N, n3 U# Q4 ~& h- t9 c

  841. % U+ W5 H9 k& L' K" v  Y
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    5 I  `" ^- W% V* m, f
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */; j' |. J3 P- g: D6 Y- u1 M& _9 U
  844. }
    ; Q! d+ T& h7 U8 P( ]6 t+ P
  845. % P$ ?1 @' G: x+ D
  846. /************************************************************************/
    ! X% X4 R) o; `) x
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    0 o  R0 ^5 o+ O- n3 M$ @$ F& B
  848. /*                                                                                                                                                */
    % z2 d9 X0 u- [+ m9 [) S9 j) _5 _
  849. /* This procedure erases the entire Chip.                                                                */
    3 [) \# j, u* }/ i3 X
  850. /*                                                                                                                                                */
    ( M- b6 e( \* ]# N4 P( y
  851. /* Input:                                                                                                                                */$ M2 _2 o7 k) b; I0 a
  852. /*                None                                                                                                                        */# [) x+ a( }1 s. i
  853. /*                                                                                                                                                */8 ^  `5 G5 x# B) x
  854. /* Returns:                                                                                                                                */, |; `) ]7 e+ N+ X
  855. /*                Nothing                                                                                                                        */. p7 O& w. G6 t5 h
  856. /************************************************************************/
    8 k6 k5 s" C' y) ?. R
  857. void Chip_Erase()
    + N  J+ A  P( G# e0 f
  858. {                                               
    ' e: K9 a2 I1 ]# E1 Z" I6 f* e
  859.         CE_Low();                                /* enable device */
    4 l* p, j9 v( r: D1 ?& `- n4 O
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    / @0 w$ Y3 L- _' L
  861.         CE_High();                                /* disable device */) @2 w! i) l5 G( U' F. X
  862. }
    8 v- {0 j2 ~4 l; e( _

  863. - B: s# t" m7 U5 L* g
  864. /************************************************************************/
    ; D+ N( k# U1 m- N$ y7 @- `
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    $ f- G& A/ U8 O4 \) N9 |
  866. /*                                                                                                                                                */# |' v) g  F, v& l, O: c7 ?
  867. /* This procedure Sector Erases the Chip.                                                                */! I& V! c$ }4 c! W. P  Q
  868. /*                                                                                                                                                */' s) w  G2 z# Y0 v
  869. /* Input:                                                                                                                                */% z# L9 @) d7 Y9 [; Q& P6 M
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    6 Q7 N# a* h( {' @5 I$ \/ k* J
  871. /*                                                                                                                                                */
    ) x* P, \  [. l. z
  872. /* Returns:                                                                                                                                */
    8 b* ?# _+ Q( q3 V
  873. /*                Nothing                                                                                                                        */
    * |/ L. r1 F$ D' U) f
  874. /************************************************************************/$ R7 j1 s$ y- `+ A+ T: G
  875. void Sector_Erase(unsigned long Dst)( @: u+ ^$ [# f8 v
  876. {# b- f( y* h8 [
  877. ! U' I7 ~7 j! m  n/ _0 E
  878. * s0 z. g7 R& B. [8 J- v2 T9 g6 Q
  879.         CE_Low();                                        /* enable device */
    1 B, d* p, g$ N4 q
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    ; W9 {/ n/ o. K5 s
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    . j- U. r- `, h' |% T3 }6 g
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));! e2 h- J$ v5 n0 j( R- F
  883.         Send_Byte(Dst & 0xFF);1 `3 t0 ]* f9 T& G( j
  884.         CE_High();                                        /* disable device *// F% ]6 x6 [/ H
  885. }       
    3 ]8 k3 U, n' S- M% q8 C6 k

  886. ' U+ x3 l. B) f7 a5 Q
  887. /************************************************************************/& W/ E* Q1 k, X5 B
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    ) o  ]- f& @, J1 W9 e& T* ~- i
  889. /*                                                                                                                                                */
    2 g0 v! _& P* |+ P
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */  V% [9 B- R- \( R$ m& i
  891. /*                                                                                                                                                */
    4 p' A1 L; y. R$ y; T9 ~% |
  892. /* Input:                                                                                                                                */
    2 A9 M" H, K/ I9 N+ L: M
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    2 c% y" Z7 t" \
  894. /*                                                                                                                                                */  [0 J2 s: A# t0 |
  895. /* Returns:                                                                                                                                *// {- d, ~0 L$ J( @1 A7 g( Z; F
  896. /*                Nothing                                                                                                                        */: K; I& I& t" S8 v! b# X0 V  P
  897. /************************************************************************/  L  C/ E  l; @- f& r
  898. void Block_Erase_32K(unsigned long Dst)
    4 r) t6 ^8 f' t7 Z! x
  899. {
    * j9 T) g3 h* A  N
  900.         CE_Low();                                        /* enable device */. v( k) ]5 ]1 l
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */0 o# [) ~! G+ H0 J8 M# R4 x' w
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    7 T* A' T0 w5 n, ]& Q+ }
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ' \% Y2 Z" X5 ?9 Y
  904.         Send_Byte(Dst & 0xFF);  n' a5 _) R% f% X
  905.         CE_High();                                        /* disable device */
    5 f2 r$ W) x/ H& s6 d; m/ X- y
  906. }$ G# h( C/ {& F8 T  C

  907. $ x0 I# }7 {9 L  t
  908. /************************************************************************/7 R# |) S# f% O. i8 S
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */7 ]& y3 m0 F2 C. t
  910. /*                                                                                                                                                */
    ( ~) t3 H; m" ~) k1 b; B
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    ! {1 x& E$ z3 i' b
  912. /*                                                                                                                                                */
    * Q7 t' M. p6 h( U# j3 `
  913. /* Input:                                                                                                                                */9 X; u! l" w; z" S3 N
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + R: \. g4 l) }6 F" Z
  915. /*                                                                                                                                                */
    ) T7 X( V( b% F9 t) \  X
  916. /* Returns:                                                                                                                                */& w0 [+ p) o/ R( _
  917. /*                Nothing                                                                                                                        */
    % F- z/ s5 Z$ W! R
  918. /************************************************************************/
    1 _4 ]; |8 j; y% `8 a
  919. void Block_Erase_64K(unsigned long Dst)
    7 E+ y* n" M4 m# n7 B% N
  920. {* o% W9 n! s! o1 H& a! C
  921.         CE_Low();                                        /* enable device */2 ^* `7 M+ t) U* m5 r
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    # c' V5 O. N* u
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    , C6 l0 V+ E; q# @
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    0 X+ h7 Z0 u+ p
  925.         Send_Byte(Dst & 0xFF);
    / @! y% @8 J5 t8 c7 ~. D8 T
  926.         CE_High();                                        /* disable device */' I; C9 w( P7 B, i6 a3 Y3 v, x
  927. }
    8 a5 U- L: E4 ~2 D. Q3 y
  928. + p3 v# q' ?7 e# W+ V5 H0 j# t
  929. /************************************************************************/
    & n) m- A7 N- b- ~  H. w
  930. /* PROCEDURE: Wait_Busy                                                                                                        */* T$ M, w7 t, {8 ~: X
  931. /*                                                                                                                                                */
    1 s  I# m/ A7 f
  932. /* This procedure waits until device is no longer busy (can be used by        */# q2 f( C$ G) C9 U5 ?1 A) J
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */2 P/ Z- [0 z' j* H% q
  934. /*                                                                                                                                                */0 G, J; j: p  l
  935. /* Input:                                                                                                                                */3 h. p2 C5 y1 u, I# `5 g
  936. /*                None                                                                                                                        */
    ( V3 M; \1 n3 W0 f
  937. /*                                                                                                                                                */
    & `3 l1 h0 F, h& O
  938. /* Returns:                                                                                                                                */9 b  k* T# u- Q1 q0 ?
  939. /*                Nothing                                                                                                                        */7 l/ W1 `+ w1 x
  940. /************************************************************************/5 Y9 I0 o  X* r
  941. void Wait_Busy()6 {# a6 E) b' _* s' C
  942. {8 w2 u. }9 ?: C+ Y# w- F8 O" k. d
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    4 P6 |- o* F' c% F8 l2 [
  944.                 Read_Status_Register();% n4 @$ `  k& P" `! y3 c9 ?2 U" J
  945. }: n5 t2 g0 c  U  A- t* |8 n- @% D
  946. , R5 }# m/ ~1 G; C+ _+ J  o' D; Z0 m5 @1 Z3 w
  947. /************************************************************************/; _% G9 G4 c! P' d
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */' S3 f, N1 e, P& K& _
  949. /*                                                                                                                                                */
    ( A3 F: f  W8 T! r$ @
  950. /* This procedure waits until device is no longer busy for AAI mode.        */' I! l% T% `; Q4 ~% K
  951. /*                                                                                                                                                */% D4 C# H2 g. r0 n& K; e
  952. /* Input:                                                                                                                                */3 t4 e* `# O; a
  953. /*                None                                                                                                                        */6 u0 `9 z! j3 O6 J' R- a
  954. /*                                                                                                                                                */
    5 ^$ @+ V  i; B: {1 f
  955. /* Returns:                                                                                                                                */
    0 q: F9 ~2 G6 B; Y- y/ d
  956. /*                Nothing                                                                                                                        */. @" R& r) B. w1 X& C
  957. /************************************************************************/
    - b& D2 T" ~1 V- [, ]: ~
  958. void Wait_Busy_AAI()
    # A$ x& X7 ~/ K- C2 l
  959. {
    # e8 g) [  y/ v! C$ @# L7 [. ^
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */' p3 n5 S+ [# v/ u  {* v
  961.                 Read_Status_Register();% ^& G" X' q4 w5 R8 U  Z1 |5 D( w5 J
  962. }9 a0 v; f# n, x& I7 A

  963. & n% n! `" F+ w& R( [! z
  964. /************************************************************************/
    9 K, V/ d2 O% U- ?% m  T) [6 v9 E
  965. /* PROCEDURE: WREN_Check                                                                                                */
    * `5 X: _( N/ E
  966. /*                                                                                                                                                */, U% l: `4 j- \* R8 [/ ^
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    ( p  d) c2 ?1 d
  968. /*                                                                                                                                                */) Y2 ~( \% N6 c8 R1 s  a
  969. /* Input:                                                                                                                                */
    . U# J# l4 a8 y0 q- p
  970. /*                None                                                                                                                        */
    ! u/ y4 v  `+ _
  971. /*                                                                                                                                                */
    $ o; R5 E) h# }
  972. /* Returns:                                                                                                                                */
    ) V, V, a8 l/ W6 i5 R* L2 ]5 V
  973. /*                Nothing                                                                                                                        */2 g5 h: c3 G% f& d" I5 ^
  974. /************************************************************************/% q% S! s1 y, g4 |1 T+ f& r( t
  975. void WREN_Check()& i+ V+ U/ s* [2 `  q
  976. {
    . U2 D& B7 Y2 D  W- ?, W5 e
  977.         unsigned char byte;
    4 d7 }9 U7 |4 r5 R
  978.         byte = Read_Status_Register();        /* read the status register */
    : W- A# ~$ P! Y
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    , Q# U* c' f0 u+ c' w2 p
  980.         {
    ! D" J1 _3 q1 l9 _+ a  x7 O
  981.                 while(1)! N- h/ w5 m0 N# K- m+ k/ e
  982.                         /* add source code or statements for this file */$ h9 _' j0 w0 N+ F- I: L2 i) M% e2 W
  983.                         /* to compile                                  */
    / T, K) Y$ o" P5 n
  984.                         /* i.e. option: insert a display to view error on LED? */. B; q5 b. p! O/ p2 n5 c  m
  985.                  
    . b/ M' S2 E' i( w* g
  986.         }2 g* M  l  H& \5 i9 m: Q: t
  987. }5 d, o& b. \) n! z/ ~6 Z4 ?2 ~1 b$ t

  988. 8 w/ z( ^' s9 ~+ O) s( t0 N
  989. /************************************************************************/' W2 f4 Z$ s/ {$ }% h; V
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */  S. S! a1 ^5 Y! m/ l. G
  991. /*                                                                                                                                                */. a. g7 P$ a# `. X4 h9 C$ G; l
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    % m( T. ~; m1 E2 T/ [/ o
  993. /*                                                                                                                                                */& l( B2 E; [" a% B2 l- A
  994. /* Input:                                                                                                                                */
    / c+ M( N* Z: `$ t  b6 b
  995. /*                None                                                                                                                        */
    " R& V- h4 v* F: `7 D2 b$ x5 ~
  996. /*                                                                                                                                                */
    2 n  C4 n1 B: }8 x; Y
  997. /* Returns:                                                                                                                                */
    * a/ A# g) ~) d. p6 {* p% j
  998. /*                Nothing                                                                                                                        */
    ( Y  U: F! u  d% u2 f4 K& M3 M
  999. /************************************************************************/# e% g1 d- Y/ q- ~. {; n
  1000. void WREN_AAI_Check()  T: ?! X  ]0 S
  1001. {* e- P1 n; [6 Z! j7 B+ Y
  1002.         unsigned char byte;! A& `7 B' `" e" U1 b
  1003.         byte = Read_Status_Register();        /* read the status register */
    2 S+ p( S3 _+ m6 l/ w+ v; g9 T/ K
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */9 |6 _/ q: C8 K6 P
  1005.         {9 @# @+ }3 F* d4 P" `
  1006.                 while(1)               
    6 M3 ?* p3 f' l! k1 f: s. U
  1007.                         /* add source code or statements for this file */' n8 r8 z& P" {' z% u: B" P
  1008.                         /* to compile                                  */  M$ y  ~7 }/ v7 X0 Z
  1009.                         /* i.e. option: insert a display to view error on LED? */
    + W; q/ k. x) K9 _' A( G7 ~8 E

  1010. " L. c4 Y! r  d+ {6 y. t  a
  1011.         }
    ( Y) y1 J# d& c% i
  1012. }
    & G- J$ N9 }6 Q6 a; C

  1013. ' W" l& m  k6 a+ z
  1014. /************************************************************************/& i3 i1 |2 L( Q( W4 k9 ?
  1015. /* PROCEDURE: Verify                                                                                                        */6 H( A$ y/ L6 [4 n
  1016. /*                                                                                                                                                */
    8 u1 V8 Y9 Z6 E# C( p
  1017. /* This procedure checks to see if the correct byte has be read.                */7 P5 e$ L( m( \' k" x
  1018. /*                                                                                                                                                */
    ) Q$ H+ N# [% b  N
  1019. /* Input:                                                                                                                                */
    . X5 V9 Z* ~7 v
  1020. /*                byte:                byte read                                                                                        */  [8 ^' ?1 z$ r9 A7 U
  1021. /*                cor_byte:        correct_byte that should be read                                        */( v. N% _& y1 p0 v4 R
  1022. /*                                                                                                                                                */
    2 x3 h' g; M9 Q7 Z8 }
  1023. /* Returns:                                                                                                                                */
    * o0 O* j" T0 f1 q7 r
  1024. /*                Nothing                                                                                                                        */
    7 B* U0 y; ^# P+ Q3 c( G' G* g
  1025. /************************************************************************/
    $ y3 k0 |1 T$ q' m
  1026. void Verify(unsigned char byte, unsigned char cor_byte)7 `7 |2 i: u. |4 D  R1 A; ?' o
  1027. {
    # S7 H2 I9 k2 {* e; J  z, @& u5 w: P( m
  1028.         if (byte != cor_byte)
    ) h! I0 f0 q( r6 g6 }& e
  1029.         {7 k! H3 F! R8 W: J' U: V
  1030.                 while(1)
    . t9 e. o+ |/ @% h' b
  1031.                         /* add source code or statement for this file */5 }8 ^9 _4 b$ o* D
  1032.                         /* to compile                                  */
    & o, W: v. e9 n9 c
  1033.                         /* i.e. option: insert a display to view error on LED? */+ q1 u- w* G+ @7 ?' e6 `
  1034.                
    3 _% N% O" O/ u' n' o
  1035.         }
    ) Y/ p( R! q/ y; O* H+ ?$ B7 A; t
  1036. }4 P$ r$ s' Z: i( u3 w8 u1 c  |
  1037. 0 B$ n7 G7 \/ U% s4 i1 g0 u/ C

  1038. , T2 ?2 i& k" a' T5 `) F
  1039. int main()) _7 |' {. l5 H7 y% G
  1040. {" S% f( z% }* F. }0 m  e2 w

  1041. 1 \) M' |4 Q9 @) E- e3 B: c
  1042. return 0;
    6 N: y3 ~) G0 P( t
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
% H2 ]+ o6 n, T0 A8 m   main()/ N1 F' L+ ?0 V6 ^; Q
   里面怎么是空的呢?5 ?9 a% s: ]; F
   发一份给我吧! ?, t1 x! n% _) T2 [- d
mail:luyijun2005@hotmail.com1 v' V6 V' [+ `/ A; g2 Q" Y3 x3 _
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
# @. l5 R  U( x, W% j6 L$ `9 k4 ^1 I: M6 P, S# y% k& d
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。8 i# l6 L6 Z' C7 p2 A, g; M  ?) @
EC的代码在哪跑,你看DS的说明,每个EC都不同的。
6 U. |# O) \: r- U& O1 h5 y2 COEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
( w; n" k' N6 F! D1 ]7 K上面几个问题是你没看任何东西而白问。+ C' b% p, ?/ f7 ^8 _

1 L) a, |# c: e, b! X" Q" B/ I至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

0 t4 P) D0 ~' }( M' w4 Y+ k关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
* b  B7 D5 c, @  u$ c9 Y5 `! J) {; x, o
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”* q, W' S5 i, T7 F; O7 Z  N( C* h

  s* V% @; Y* ^. V, c# h* x, M' i* ~关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...
: B3 X0 {, r& F0 y  I) E9 v1 J2 L# C5 O' Z# l# g
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
2 q# z$ a) u3 k+ q" k: w& u9 ?" H似乎要把SPI能support 到最大,这EC chip应该有好卖点4 j) t8 F- h' ~
BIOS功能要不要强大,也就决定了SPI Flach的大小2 @2 G3 g1 ~$ [4 m, G9 Q5 s
我是这么想的~让OEM去决定要挂多大!# y# C% k6 Q1 M6 H5 s! O
如果我司有BIOS工程师就好了~哈
  ~, A0 ~. R- J* Y5 N; NWPCE775应该算很新的东西,来看它支持到多大?
* n( T9 v7 l% l$ c$ b7 X/ \' d" n1 y6 s! p6 R- f
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte5 ~% e# i) g, Y
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
( \1 {7 o# m; ?7 E- H1 H! u2 f4 I' q4 ?8 A# y, x  c
这份driver收下~希望以后有用到
8 `& z& Y. i8 p* @8 E谢谢bini大大
- |1 J. m2 s5 Z" u3 G5 N
, T+ r! a( }; p很新很新的新手,如有错误请指正 (准备看第二家的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()+ e" s: _& A9 k6 u! e% V' L1 w
{
2 y9 J: R0 f, v/ J* L        unsigned char temp = 0;
! y& Y- H8 r: f, n        CE_Low();# I8 H4 U2 R5 C; S% Q
    while (temp == 0x00)        /* waste time until not busy */  ~, U- V* ~5 P  C+ H. u) {& G
                temp = SO;  T! a0 W7 p+ d
        CE_High();
5 Y7 p3 w9 G# k2 d5 Q5 Z& H% E}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)1 a/ t- m8 y- `
{4 D& i  V: W  _9 }& _3 f8 R; w
        
& A. R% b+ y, ?' q. \9 P0 b5 N        unsigned char i = 0;" Q: S3 s! g  }) L/ _
        for (i = 0; i < 8; i++)0 a; e5 \7 O7 i+ ?# ?
        {/ _! ]* A8 {' ~4 ~- V/ {
               
' `7 [  @, d* p3 D: Y, `5 n, |                if ((out & 0x80) == 0x80)        /* check if MSB is high */" ~( x$ d1 Z- t1 @
                        SI = 1;2 e3 r8 Z. \' M0 F7 }* L6 @
                else6 d* g. Q$ x/ \& K
                        SI = 0;                                /* if not, set to low */! ?+ A$ r" J! G( ?" i! T
问              SCK = 1;                                /* toggle clock high */. Y2 Q- X6 E' [, ]" ~2 I
   题            out = (out << 1);                /* shift 1 place for next bit */& [0 H* R; J4 t8 E& U
                SCK = 0;                                /* toggle clock low */- U  N6 Y$ ?& I- p
        }
7 V4 Z7 ?5 q3 \0 i. }9 R5 u}9 ~0 Z1 i7 W4 }' H
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-1-12 00:45 , Processed in 0.079823 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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