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

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

[复制链接]
发表于 2007-11-13 11:07:18 | 显示全部楼层 |阅读模式
EC挂接8Mbit SST25VF080B的话,可参考和学习,其它的SPI FLASH雷同。
  1. Software Driver- d: G4 e5 I' i0 z( }/ ]/ D
  2. - B2 a; K1 i6 o. a
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    - C; B$ _# _2 G& ?
  4. 8 N! P# U$ ]0 m4 Z( f9 ~
  5. November 4th, 2005, Rev. 1.0
    / |/ }; a4 L# Y& M$ R. R4 u% h
  6. 5 F5 O6 \# c! O- l* @# E6 ^5 {0 h/ d
  7. ABOUT THE SOFTWARE1 m, z. h9 t( n* ?, x
  8. This application note provides software driver examples for SST25VF080B,6 n: g1 Z$ E5 P/ ~. G/ D
  9. Serial Flash. Extensive comments are included in each routine to describe
    ) H4 c- ]# t5 n
  10. the function of each routine.  The interface coding uses polling method ) I/ u  G. @$ b
  11. rather than the SPI protocol to interface with these serial devices.  The
    9 c8 O/ r$ Q2 k6 W9 m
  12. functions are differentiated below in terms of the communication protocols+ X6 R% a9 F3 \) `4 o  x8 O- i
  13. (uses Mode 0) and specific device operation instructions. This code has been 1 l& `3 p% D" Q8 w: J7 o4 a
  14. designed to compile using the Keil compiler.
    5 U9 @+ [) P) b8 b, s

  15. 8 ~3 C. e2 A7 q& s1 E% m2 f- O+ z

  16. 5 b* E- Q. ]  J' |% A
  17. ABOUT THE SST25VF080B' V* a$ t/ j* r3 F
  18. / I' j: b  U2 p, A# b0 P4 M
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    ' b" t! v& n! _. H5 @% ^! ~3 r% ~
  20. conjunction with this application note for a complete understanding
    3 F. o  H1 w3 F7 t/ n: n- C; {
  21. of the device.. S" f7 x, @) d/ |" Z& W
  22. 9 I% L) C! v( W) o8 _9 W
  23. ( O( n' I1 d) ^; M/ ]5 }/ v
  24. Device Communication Protocol(pinout related) functions:/ ~9 P3 m- @& N
  25. * @. k8 ]6 f( @! M  q
  26. Functions                                    Function
    9 z8 g4 v& u! D9 V( t
  27. ------------------------------------------------------------------
    ; T2 X7 z  a  @  [6 W# n$ U2 J6 |
  28. init                                        Initializes clock to set up mode 0.
    ; J1 W* a! r, W+ V  W( _
  29. Send_Byte                                Sends one byte using SI pin to send and - U5 d1 ]$ s6 J" `9 A
  30.                                                 shift out 1-bit per clock rising edge
    3 F* F, ?; R. l- i  ^9 t4 c- L
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    / ^" |3 d, S+ K$ c  _0 |' l
  32.                                                 in 1-bit per clock falling edge
    ( T' O# L7 d' Z% E+ x9 h
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming4 ^9 Y8 a5 H' s: ]% z& J/ k
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    3 n. w% D7 T0 J2 o3 S3 k, ~6 Y
  35. CE_Low                                        Clears Chip Enable of the serial flash to low/ t. u, r9 q9 R
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    % m, I5 d/ d" m% D$ V' Y
  37. Unhold                                        Unholds the serial flash
    + {! Y  m4 }1 ~6 t
  38. WP_Low                                        Clears WP pin to make serial flash write protected6 ^2 R, Z( j% `% K5 B2 o( D
  39. UnWP                                        Disables write protection pin/ Z3 z) [) s: T8 b  k9 y
  40. " K' [7 p6 C5 L
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code* s) {6 {# d) l& m1 c
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    , F; q4 s) g, O/ u
  43. software which should reflect your hardware interfaced.          / m9 x. K0 r7 w( y' u) u( X4 D

  44. 9 d% j6 S( w6 C# v/ ~
  45. + r3 e. ?% N* O; g
  46. Device Operation Instruction functions:' j: b, ]& n; X& I, \! W% F

  47. " V+ G% L& E2 w( T- |. U% R
  48. Functions                                    Function) e0 X' u1 o; ^
  49. ------------------------------------------------------------------
    ) I2 T; ~* W5 R9 P  [, M( i
  50. Read_Status_Register        Reads the status register of the serial flash
    $ U3 ~8 N. p, s1 W  m
  51. EWSR                                        Enables the Write Status Register
    3 f% u# i; @/ Y3 Y( F( r
  52. WRSR                                        Performs a write to the status register
    * A- q& d7 ~3 E9 \  `; C9 D6 k
  53. WREN                                        Write enables the serial flash
    & N! t9 m! x% }/ M9 }
  54. WRDI                                        Write disables the serial flash% q$ o9 H! ~2 h% D: k* _- [
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming/ ]' E; Y* K- ~4 d1 p' `, X, x
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming8 I& J: }; H- h8 i- |2 e
  57. Read_ID                                        Reads the manufacturer ID and device ID) H% G9 Y! Z$ }3 |
  58. Jedec_ID_Read                        Reads the Jedec ID
    & l2 S5 ]& o/ L, r& |6 G
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)4 `( t) u" r+ U! z: v! x% f2 v) O
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency): Q( I  I  B- d1 }& L# M- n9 S
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)+ G+ P1 Y  y* U; V1 u% J' Y
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    ) k9 w8 J# H2 r
  63. Byte_Program                        Program one byte to the serial flash9 S4 v, R5 _6 N* Q4 h
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    0 o: t1 I* Z& ?% |! I8 ~. X
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation5 h. M8 T8 |, ~& b  W
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY, Y# T0 |0 y1 k4 ?8 r$ P
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    5 r5 k1 b% \. \& K6 U
  68. Chip_Erase                                Erases entire serial flash, K, w4 v3 j* z' b( f/ j! l
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash+ H4 A. N) g& E; t7 Y5 I8 D: Q7 F7 C
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash+ Z# C6 W- y5 i" a  R5 `$ M
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash. a, b! ^  ?& [
  72. Wait_Busy                                Polls status register until busy bit is low1 \5 u, N7 ]4 l+ N# M4 L3 h- b, I- R9 j
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming0 f9 p7 _' K; n$ `. O+ P
  74. WREN_Check                                Checks to see if WEL is set% H3 V5 O. |  n+ o
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    ) Z+ {& }0 Z1 I! ^
  76. 2 j3 w& D, s- b+ R" Q( J' A
  77. 6 L8 G8 l' m5 x- _& e# P
  78. : b4 R  T" k1 q
  79.                                                                      
      U/ l& Y0 U& D0 K. |+ ?
  80. "C" LANGUAGE DRIVERS 5 ?, [& v6 N. J' }6 B1 G1 m
  81. , |  j4 {+ G+ S& L6 C9 z
  82. /********************************************************************/2 h; e. Z4 }* X3 X/ P
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */9 w* ]& j) N0 Y
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    9 O( h2 C5 b  K) K  m
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    8 L4 G# H7 O' ?- C1 ~3 S
  86. /*                                                                  */8 h' I# r6 @. W3 o
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    - u# ~1 a/ o& j, s1 P! A; M$ r$ ^
  88. /*                                                                  */
    6 w% h9 d$ s) c# S
  89. /*                                                                                                                                        */
    " q* [0 t" Y4 |: Y: h1 a' n  _( \
  90. /********************************************************************/
    4 m' _1 ^( }$ R  }$ g

  91. ! K% k4 h! G! r5 g/ G& H
  92. #include <stdio.h>6 T" ~, {! B1 w3 O1 p
  93. #include <stdlib.h>8 F; {  c( z6 S& b0 m( }; Z# j9 |) w
  94. / f" [# Y( B% u) O
  95. /* Function Prototypes */* l7 P5 F# m; p, |& {- m; Y8 L  X3 }. B  f* U
  96. 3 s) G! G% W7 |( r/ ?
  97. void init();! S" a! g  {1 W- w# {+ y/ N
  98. void Send_Byte(unsigned char out);  t+ E6 f5 T: p
  99. unsigned char Get_Byte();
    ' ^# Y# X) y6 B4 B, F
  100. void Poll_SO();
    ! d* @" _# Y+ _
  101. void CE_High();* s0 R  }. c3 l# m: G3 ~+ ~
  102. void CE_Low();
    - m, R3 w. W! b2 c  f& {
  103. void Hold_Low();
    ) R$ l: q! D8 W) ~, d
  104. void Unhold();: F  W1 g( V* m" h& W' @3 K; ~" Q, k
  105. void WP_Low();
    # M. d- q& p* F! s
  106. void UnWP();
    ! H9 U# Y/ G% B# d6 f( m# a) W
  107. unsigned char Read_Status_Register();  M, R+ J/ G6 w9 ]' d% R" E6 v
  108. void EWSR();# H8 K/ p+ A. e) C
  109. void WRSR(byte);
    5 l( B% A+ H6 b, C9 d/ g
  110. void WREN();
    " @# {- e4 M4 ~/ ]
  111. void WRDI();
    4 h+ T2 N6 `( Z
  112. void EBSY();
    ) F* E4 ]. ?* d
  113. void DBSY();4 \3 I# K3 y( I7 E  T4 X
  114. unsigned char Read_ID(ID_addr);2 {5 z3 g3 O, D0 r# O3 {
  115. unsigned long Jedec_ID_Read(); % s/ V! I! d# u& m+ }1 f
  116. unsigned char Read(unsigned long Dst);  ~1 O0 X' G$ [7 p: m) y* l+ G
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);5 l' C0 C( o8 V. K! c! i* M9 p0 }" ~
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    - L# b, h  o: g, @
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);( _! m" r  w8 H& W! q% j
  120. void Byte_Program(unsigned long Dst, unsigned char byte);* J* o# E4 K  i7 P8 s" U8 t. I
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    ; U/ n6 ?9 p$ @$ `# d
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);( A1 C6 u% m/ C/ w1 f
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);* z4 z- {. i; J5 v9 K4 D
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    1 d9 _  j: }8 _1 t
  125. void Chip_Erase();( O9 T0 {0 |' w$ R/ j
  126. void Sector_Erase(unsigned long Dst);1 S* H  {9 ~/ D% ^3 Q* ~0 S- ~
  127. void Block_Erase_32K(unsigned long Dst);+ N0 |1 J8 f; R1 _  B! A) p0 o
  128. void Block_Erase_64K(unsigned long Dst);" d- s) ?" |/ z
  129. void Wait_Busy();! f, d4 |2 O! r
  130. void Wait_Busy_AAI();; L$ W0 y: o( p/ S; l
  131. void WREN_Check();
    : e) {2 I+ [, }9 D1 P# J; l( }
  132. void WREN_AAI_Check();+ H4 J- K* C$ Q: j5 m# B

  133. 8 @0 z6 r; e- u; ]5 I
  134. void Verify(unsigned char byte, unsigned char cor_byte);8 q& n. L! [; S6 D4 Y$ Q  }" |

  135. # {9 F& B* A8 P) t8 T7 X; Z
  136. unsigned char idata upper_128[128];                /* global array to store read data */" ?1 o. h" w# ^/ F% t5 P
  137.                                                                                 /* to upper RAM area from 80H - FFH */: X: O# Q" n1 @# L$ u/ n9 m5 g
  138. 0 J: g" Q/ {* F1 R7 _' c" D
  139. /************************************************************************/
    5 g6 ]) M3 ^3 H- Y: i/ Z! h
  140. /* PROCEDURE: init                                                                                                                */" M9 j, n( X. |3 a% T
  141. /*                                                                                                                                                */
    / K5 b+ H9 x5 g) q  z
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    8 J' A; d  s2 o6 M- \" w* U
  143. /* setting up mode 0.                                                                                                        */
    / Y0 Y! C5 l: B: F3 T2 j1 S+ w
  144. /*                                                                                                                                                */5 R- E5 M4 o  C! r
  145. /* Input:                                                                                                                                */
    ' U3 z  s) b/ @9 |. ^8 o: M. s
  146. /*                None                                                                                                                        */
    & a' S! \& I- N, D4 ?) j
  147. /*                                                                                                                                                */
    6 {7 l* j! |7 U$ ^# J# `6 \
  148. /* Output:                                                                                                                                */
    / ~/ h- O4 Q. M5 @: c  ~: T
  149. /*                SCK                                                                                                                                */' ?7 f: ^& H7 i: |. j3 a
  150. /************************************************************************/, @* K2 Z8 o& D3 _" x
  151. void init()
    & `1 H/ T% w- W
  152. {
    3 L7 n3 I/ Q3 M+ I
  153.         SCK = 0;        /* set clock to low initial state */
    + p/ a6 F, j% W6 ~8 l% ^# U% r- c
  154. }% Q4 m4 Y6 D  |3 m  y
  155. ) F  E5 C4 @, Z; f( o. {
  156. /************************************************************************/
    4 U# H: C* |" Q  p' R; s8 v
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    ; Y# e8 i8 I# k: {9 ]# f
  158. /*                                                                                                                                                */
    1 E; z: C+ n  q
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        *// d2 B4 g5 A( W! C' s- I
  160. /* edge on the the SI pin(LSB 1st).                                                                                */+ }* Q% `. |; t  [
  161. /*                                                                                                                                                */7 ]8 w4 c0 N$ K1 q* w
  162. /* Input:                                                                                                                                */
    - Y/ B( r+ X+ J# q. a% f8 ]
  163. /*                out                                                                                                                                */
    - \7 f; h' I& k$ Q. S4 ~& O
  164. /*                                                                                                                                                */
    : K) K! Z4 ^* d. \# Y
  165. /* Output:                                                                                                                                */
    9 S5 ]: {* x6 ?" Z3 W: j6 S9 y* C# U
  166. /*                SI                                                                                                                                */" R3 P% S! y8 l7 D" \
  167. /************************************************************************/
    ! {/ V6 Y8 F8 g/ O) T
  168. void Send_Byte(unsigned char out)
    - r5 z. i& q# A
  169. {
    6 \; v* m9 G- X$ l
  170.         2 Q! H9 D, W4 \8 x
  171.         unsigned char i = 0;
    % u8 ~( B# ]- e$ F& G& x8 k
  172.         for (i = 0; i < 8; i++)
      h$ z9 L/ P' E& l! {
  173.         {
    9 L8 @; |$ @9 r
  174.                
    7 S1 f" h# F' W, j: r$ K' R
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */. W$ z0 @1 H* L3 @& i
  176.                         SI = 1;
    6 _  h# d8 R: v$ Q( i  z% M
  177.                 else- C  e; }  V+ }# t1 t! ]
  178.                         SI = 0;                                /* if not, set to low */
    4 p( n8 v1 h. O" b3 b
  179.                 SCK = 1;                                /* toggle clock high */" W( q  Q# B( l+ o1 H( M; C
  180.                 out = (out << 1);                /* shift 1 place for next bit */6 j5 k' i6 F$ n
  181.                 SCK = 0;                                /* toggle clock low */
    1 t% G( ]* X. h! v
  182.         }
    & n, W: ]  C; e/ i0 t/ n+ ~" X
  183. }1 A* a5 `( r1 ~- O, m
  184. 3 K/ H1 v2 D. }7 U# X
  185. /************************************************************************/7 Q) E! d. I. X: h. U9 D
  186. /* PROCEDURE: Get_Byte                                                                                                        */3 L) v2 u9 b. g/ `
  187. /*                                                                                                                                                */
    # q/ `# k- N" O3 P
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    2 z: m$ L! u0 [1 l8 G" ?4 I
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    . `3 ^* ]# c* I- `$ i- G6 \/ T' y
  190. /*                                                                                                                                                */4 ~1 o3 A0 ~6 K1 T/ @" [$ |* N; \
  191. /* Input:                                                                                                                                */
    $ {9 G6 a! U7 |% L8 O
  192. /*                SO                                                                                                                                */; V7 \* q! f5 v: L7 M: |
  193. /*                                                                                                                                                */: k$ w* W% k! o9 h! R. m) d' l
  194. /* Output:                                                                                                                                */3 K' Q" A+ H# @  }4 u
  195. /*                None                                                                                                                        */
    : k8 w: m3 T. T+ Z, C7 d5 d. j
  196. /************************************************************************/, R9 E( s4 G7 ?- H9 p  P
  197. unsigned char Get_Byte(). a; X8 u4 Z8 m& K# l1 S1 i( X
  198. {2 Z; H; I7 ?& _9 v. ^
  199.         unsigned char i = 0, in = 0, temp = 0;" s) w' C. s' Q6 X/ P0 A
  200.         for (i = 0; i < 8; i++)
    : S8 X" [6 k* ~$ X; C
  201.         {2 s; w4 T+ I) O* Z8 @
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    6 `* E  `  ?! W. a; L. R+ v4 ^
  203.                 temp = SO;                        /* save input */
    : n2 v& g8 H" _2 `5 \) D
  204.                 SCK = 1;                        /* toggle clock high */
    ; s( N) e% R1 _* P! I. L, g
  205.                 if (temp == 1)                        /* check to see if bit is high */
    , Q6 D1 T3 S5 |; F* K8 i9 l
  206.                         in = in | 0x01;                /* if high, make bit high */6 {+ ~4 a$ o& Y0 l, A* Y
  207. " P6 r% T& S& c$ N$ G
  208.                 SCK = 0;                        /* toggle clock low *// ^1 U6 O3 K  w) T$ x1 U0 T

  209. . J4 i0 M% d3 _# B
  210.         }
    . Z! \. e5 p0 N0 |& {; V
  211.         return in;7 J9 c8 U. n+ r# @4 g- W
  212. }2 `7 N! _' F) u
  213. 3 {& V( q: D7 i2 I
  214. /************************************************************************/$ N# s4 S5 Q1 @
  215. /* PROCEDURE: Poll_SO                                                                                                        */' G' G& E( r9 P3 _
  216. /*                                                                                                                                                */
    6 y8 a" `0 v" a/ p
  217. /* This procedure polls for the SO line during AAI programming                  */
    1 w! a, O, f8 H- T" s, w
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/; D) L! Z. e  b
  219. /* is completed                                                                                                                        */
    1 b1 _) n* t/ |6 n; }: Q4 C5 N
  220. /*                                                                                                                                                */8 _1 @! d% J. e
  221. /* Input:                                                                                                                                */5 X- `6 O* O4 Q3 x3 h* L3 H
  222. /*                SO                                                                                                                                */9 u- L9 P; z. F! Y0 m
  223. /*                                                                                                                                                */% ?" n5 \4 u+ o5 T
  224. /* Output:                                                                                                                                */6 C( |$ L5 R4 a; z% o
  225. /*                None                                                                                                                        */$ T# M+ ^$ ?* ]
  226. /************************************************************************/# a; w5 ^( S1 s; A% J
  227. void Poll_SO()
    * M. A: V3 P4 G( P
  228. {6 H( k$ G4 s. o% d/ R" S, v
  229.         unsigned char temp = 0;; C! c; r6 g5 A% P: E0 L
  230.         CE_Low();
    ) ~3 {7 O" Z: f1 ?4 B% Y: {
  231.     while (temp == 0x00)        /* waste time until not busy */
    * j/ u1 k9 ^6 v- J6 ]! K  l
  232.                 temp = SO;( A: y( Y6 T* y# q: b$ F/ [' N
  233.         CE_High();! G/ c- t, e( m! C
  234. }
    , \) ~* p& v3 d# C4 Q
  235. 4 R: M( j5 ]+ z# a5 H$ R- L% D& c
  236. /************************************************************************/& B7 A" E& x! K& k4 W
  237. /* PROCEDURE: CE_High                                                                                                        */& m2 i; L- F# [
  238. /*                                                                                                                                                */
      \8 I5 r/ i+ z% b8 d, t
  239. /* This procedure set CE = High.                                                                                */( ?0 H: G6 R# M5 k. _$ s
  240. /*                                                                                                                                                */
    . ?5 V+ s; R/ E
  241. /* Input:                                                                                                                                */! c; k9 K0 v' J
  242. /*                None                                                                                                                        */2 Y" B+ q/ P0 R  N7 q3 u
  243. /*                                                                                                                                                */; \$ Y- r, j# N, s. B9 z
  244. /* Output:                                                                                                                                */
    6 [; ]4 y  n3 J
  245. /*                CE                                                                                                                                */
    & r& s% C% a$ R% I# {2 B
  246. /*                                                                                                                                                */% J6 N9 l8 P( x% x+ @" Y9 v# M: x
  247. /************************************************************************/
    $ [2 `' {: a. q$ y8 O  k( o- Z, D
  248. void CE_High() & [7 K/ K5 q0 E4 |
  249. {( A/ ^) Y4 c' R8 h1 i, U. d
  250.         CE = 1;                                /* set CE high */
    3 z0 b3 G  \6 j
  251. }4 [! z! t0 L7 [7 x* V7 w

  252. # O; N, i- ?* W; S, F* f
  253. /************************************************************************/% S) Z  ?# ]1 Z* b1 b# k) w& E
  254. /* PROCEDURE: CE_Low                                                                                                        */
    8 ~  d( u* S) Q/ c$ c1 w% k. O; ~# Q% D
  255. /*                                                                                                                                                */( S+ ~) e; ~0 I0 N* y+ V7 w+ [
  256. /* This procedure drives the CE of the device to low.                                          */, \# a; i' e6 k8 C9 K% j
  257. /*                                                                                                                                                */5 e3 G4 T9 q  E( e4 z
  258. /* Input:                                                                                                                                */
    6 X( X9 V$ Y% T- g( d# u: H1 F, h& K
  259. /*                None                                                                                                                        */
    ) R4 A8 L" T, W$ G* d; B
  260. /*                                                                                                                                                */
    ' l+ @/ m" \7 _6 G1 G$ c, s2 Y
  261. /* Output:                                                                                                                                */
    - F1 {% a& c( c$ a( E+ E7 D
  262. /*                CE                                                                                                                                */* k+ `  O5 t6 \: v$ x' T
  263. /*                                                                                                                                                */
    : _% O) f, o, t4 h' ]! d7 m
  264. /************************************************************************/
    8 x. I( w1 f; y
  265. void CE_Low() " }( x5 l2 z  J2 D3 s$ x
  266. {        5 A) T. O: ^# E/ k1 o
  267.         CE = 0;                                /* clear CE low */5 r* L4 y- S3 `5 Y
  268. }) g( u" o( k+ v4 N! q
  269. & G4 Y- O! @; r& E3 U( ?
  270. /************************************************************************/3 v) A$ r) M9 W: R7 g. d1 e& _
  271. /* PROCEDURE: Hold()                                                                                                        */
    - O2 ]8 p  M/ s: o3 @5 h- E' J* J% C
  272. /*                                                                                                                                                */
    + t  B' E: t' n/ {3 o' A
  273. /* This procedure clears the Hold pin to low.                                                        */
    8 r5 M/ [" f! v0 f6 l$ |0 H- n
  274. /*                                                                                                                                                *// O2 M0 P4 e1 Z/ D$ x
  275. /* Input:                                                                                                                                */
    ( s4 d: Y0 O3 r, S2 N
  276. /*                None                                                                                                                        */
    9 G: o7 h1 X: ^) Q
  277. /*                                                                                                                                                */
    7 ?8 _7 c  E" e' a# I4 ~5 Q
  278. /* Output:                                                                                                                                */
    1 O* p; {& l+ o6 w9 g, @
  279. /*                Hold                                                                                                                        */4 w. r  K1 k' l* n
  280. /************************************************************************/+ h9 y. \" Z: b' w; G) c; i' @# ]
  281. void Hold_Low()+ F$ Q* q( A9 Z3 @3 }
  282. {# H, M- Z  |' r
  283.         Hold = 0;                        /* clear Hold pin */5 d$ N0 I" l0 H, s8 r3 B" L# c
  284. }
    ) S+ Z& z: s' s

  285. " ^2 p% s1 N( n1 ]0 D; c
  286. /************************************************************************/- ~" @9 g4 {$ [
  287. /* PROCEDURE: Unhold()                                                                                                        */8 w1 O" K( f! R& ]* J
  288. /*                                                                                                                                                */- x  o5 e9 K0 V( a
  289. /* This procedure sets the Hold pin to high.                                                        */
    3 y" o! m0 y" h/ b' c0 w
  290. /*                                                                                                                                                */
      u6 [4 y7 u( M9 _
  291. /* Input:                                                                                                                                */
    ' x+ g8 d* m7 ^+ z% o+ l$ u
  292. /*                None                                                                                                                        */
    4 q( s4 O$ r% I9 _( g
  293. /*                                                                                                                                                */; @" c( n. A; e& e/ A* [! A
  294. /* Output:                                                                                                                                */
    * A! w& L% Q9 ]; d* c5 f) q5 V
  295. /*                Hold                                                                                                                        */
    # J$ L0 ?  M: o2 H
  296. /************************************************************************/
    ; m5 I7 [3 v2 X% N; j1 D1 g% P1 L
  297. void Unhold(); W+ c% k* F) D1 o
  298. {7 D, t2 C" W  D* ?) E8 y5 q
  299.         Hold = 1;                        /* set Hold pin */
    ' S' A0 s1 T' E! C
  300. }6 F4 j9 V2 ?3 z- N- X& f! o7 E
  301. 0 M. s5 }2 @9 S
  302. /************************************************************************/
    7 y% }/ [4 h) z5 R
  303. /* PROCEDURE: WP()                                                                                                                */  ~+ K) A& A0 i
  304. /*                                                                                                                                                */
    3 w' s3 @2 {- |! u# O- C
  305. /* This procedure clears the WP pin to low.                                                                */
    ) F  z$ d' I8 U& O7 L6 a% x& W2 Z* P
  306. /*                                                                                                                                                */; N5 o& d5 a1 E6 H$ ]! ?4 p, W
  307. /* Input:                                                                                                                                */: ^; j% f8 B, V
  308. /*                None                                                                                                                        */0 J$ P- N3 M7 ~" F+ h1 ~  z
  309. /*                                                                                                                                                */
    3 C/ V7 S2 n8 |" f
  310. /* Output:                                                                                                                                */
    ( ]7 h9 r- b# E( S5 z
  311. /*                WP                                                                                                                                */& H/ o$ S& j% p% h
  312. /************************************************************************/
    ! b  C1 n/ ~$ {0 L: l9 w7 A* T
  313. void WP_Low()1 ~$ h5 W% K) @1 k3 C: n! F
  314. {3 g+ h! E, C  ?" c8 G) h. R
  315.         WP = 0;                                /* clear WP pin */6 [- Z* n5 [6 w0 ^- {5 N
  316. }
    0 k: `6 y5 r7 \& T' r' y
  317. & d- g( K; n9 B+ _
  318. /************************************************************************/
    $ r/ i" |/ r' s+ H9 g% {4 n( P
  319. /* PROCEDURE: UnWP()                                                                                                        */( D$ i+ n2 k# B" z' q
  320. /*                                                                                                                                                */
    1 ~8 L; t% ]3 V2 F
  321. /* This procedure sets the WP pin to high.                                                                */
    7 ?$ d; G+ y8 e0 P" T" j
  322. /*                                                                                                                                                */
    7 X2 @/ F6 a" e; a5 }+ c3 m7 L
  323. /* Input:                                                                                                                                */% [5 ?3 p; Z3 b& O
  324. /*                None                                                                                                                        */
    / N5 @* @0 o7 Y$ d6 j
  325. /*                                                                                                                                                */2 w( z8 n5 P1 r/ v; }
  326. /* Output:                                                                                                                                */5 P+ F. b* Q& Q( J" [8 V6 N
  327. /*                WP                                                                                                                                */1 E( I, a# F& x" h; r- W  \
  328. /************************************************************************/: ]* u* R' u; f6 @' c" E2 T8 T1 G
  329. void UnWP()
    + R' I+ U! K: h1 U4 y
  330. {" A( p/ \! h* J" D5 Z* K; k( H( c
  331.         WP = 1;                                /* set WP pin */
    ; j/ J5 L# z# ]) f  E# L
  332. }+ `1 M" i8 B& t. y0 c. a

  333. & @7 [  z1 b: {5 r0 e+ Z! `
  334. /************************************************************************/
    * E' {5 O! z5 Q1 h: |
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    4 d" f8 A1 C1 J* N  I+ b7 _. ?4 u6 H
  336. /*                                                                                                                                                */! I" l( D5 s) B
  337. /* This procedure read the status register and returns the byte.                */
    * C- [! u2 b" H9 Q4 P. D
  338. /*                                                                                                                                                */9 ^3 Q. ?+ G& A* X% q
  339. /* Input:                                                                                                                                */
      M5 S! M4 ]& P& b* @% o% t
  340. /*                None                                                                                                                        */
    ( x1 s/ o) A# j2 h3 m2 u- q
  341. /*                                                                                                                                                */
    & X/ b, q" J, t  `
  342. /* Returns:                                                                                                                                */0 n* A* n+ O+ F% ^: Z* _: _
  343. /*                byte                                                                                                                        */6 d! Q/ ?9 n3 u, t* z3 `
  344. /************************************************************************/
    5 X9 V' t) e4 t
  345. unsigned char Read_Status_Register()3 U, R/ P4 c5 G
  346. {
    9 f7 V4 b/ W' W5 B& u5 M4 Y+ e, z5 q
  347.         unsigned char byte = 0;  r6 S& u: _$ g' i
  348.         CE_Low();                                /* enable device */
    ) H( I9 K; Q- ~* Y. p
  349.         Send_Byte(0x05);                /* send RDSR command */4 u  X8 h6 h- z& M5 `
  350.         byte = Get_Byte();                /* receive byte */
    8 G/ U- ~* f/ `
  351.         CE_High();                                /* disable device */
    . ?7 e9 G" j! t9 }! P# ]1 S, {
  352.         return byte;7 a) b; K- Z9 ?2 j" ~0 V+ V. A
  353. }; Q* e7 B$ r4 C0 V& m

  354. . m( L; E9 J' I% M* M- z
  355. /************************************************************************/
    * C; C; I" |! K- ]; g6 \1 N
  356. /* PROCEDURE: EWSR                                                                                                                */
    ; l. h6 m+ @' t
  357. /*                                                                                                                                                */; I" @" |1 j. `! V
  358. /* This procedure Enables Write Status Register.                                                  */
    & Z1 {& @, G  W
  359. /*                                                                                                                                                */
    2 N7 I9 G: k) h# M, u, _" C
  360. /* Input:                                                                                                                                */# t, W3 ^1 n9 c; Q" F% G/ p( z
  361. /*                None                                                                                                                        */! J- e, x" X  X7 M2 @1 k( Q- x
  362. /*                                                                                                                                                */
    3 ]/ N5 N' B: H- y  \. U
  363. /* Returns:                                                                                                                                */% [: ^- U" D* k# F2 K% A
  364. /*                Nothing                                                                                                                        */6 v; H7 v% w# M% ?9 K
  365. /************************************************************************/9 ^- t/ v$ J+ B# U& [9 ?
  366. void EWSR(); N4 m# Q2 J) ]8 V( K4 [3 Q
  367. {8 V) o; X& ]1 \- F. J
  368.         CE_Low();                                /* enable device */
    & [; q* g$ A8 {8 Q1 S/ h2 ^
  369.         Send_Byte(0x50);                /* enable writing to the status register */4 v3 E* a7 n1 a4 T, Y- i
  370.         CE_High();                                /* disable device */( f5 E1 r( x% m: u4 O9 t8 h
  371. }
    ! I* I- i7 T( A. S$ V5 y& K

  372. ) K7 H- c- P1 _- `* ?# _8 o, u
  373. /************************************************************************/- ]9 ~- E3 y* B7 t% p7 z; @) _" N
  374. /* PROCEDURE: WRSR                                                                                                                */
    4 K( }4 {9 K) U' g% J
  375. /*                                                                                                                                                */
    ; e- `' P9 b0 R8 G* V5 m2 \
  376. /* This procedure writes a byte to the Status Register.                                        */% i! \6 I# c- M, V* w! {1 x4 @
  377. /*                                                                                                                                                */5 k* x0 P8 \: L& i6 Y: S7 A, H9 e
  378. /* Input:                                                                                                                                */
    # }) V' L# p1 f! ~: C  a2 l" J
  379. /*                byte                                                                                                                        */  Q$ ?  z% ?+ I( X3 Z
  380. /*                                                                                                                                                */
    * @6 T7 a: n1 T. v0 |0 G
  381. /* Returns:                                                                                                                                */5 A. h* j: _' \. R" e( S( ^$ w
  382. /*                Nothing                                                                                                                        */9 ]0 Q. ~* z& e" R+ ^# V5 K
  383. /************************************************************************/
      y. `7 ^% g; u5 c* i& Y
  384. void WRSR(byte)! ^5 ~) x1 O" I. {$ A$ c
  385. {. j) Q- _1 ]4 K) v# r1 l  S) ?
  386.         CE_Low();                                /* enable device */
    + g  ]7 v: M8 o0 p; W
  387.         Send_Byte(0x01);                /* select write to status register */
    ; b9 Z# z8 e- B! y* E! M6 d
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    ; d+ R' r* N! N4 W% z' R* _$ q! u; ]
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    9 ^% @& f; w1 Q4 q( y2 j+ l1 r
  390.         CE_High();                                /* disable the device */
    , u, E5 f, Z3 O/ ?1 p$ p
  391. }4 Q" g, E5 c: T( i# U4 z

  392. & B8 ~" m' p; i
  393. /************************************************************************/
    ) A% Q8 K: `, Y$ w1 R% B3 N
  394. /* PROCEDURE: WREN                                                                                                                */
    ( E5 E2 I9 G1 r# t7 _1 @
  395. /*                                                                                                                                                */6 m: O& b. i- ?( R
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */+ t* Z# V9 W. c1 h/ h
  397. /* to Enables Write Status Register.                                                                        */( {- ]7 w: l; \$ h6 O4 ~
  398. /*                                                                                                                                                */8 S& A+ K+ s2 Q
  399. /* Input:                                                                                                                                */1 P1 q5 ]. Q) Y, i' g
  400. /*                None                                                                                                                        *// M, f; }1 S4 w
  401. /*                                                                                                                                                */
    # I( K( F2 x) @3 p+ `4 f1 w
  402. /* Returns:                                                                                                                                */. W/ T' W* [4 D# Q3 j
  403. /*                Nothing                                                                                                                        */( w4 z% E( `+ O4 q7 S6 C# |+ d( T: r
  404. /************************************************************************/7 }/ Y+ H* ^- I
  405. void WREN()
    2 q$ n5 s0 v8 ?( y" r+ r
  406. {& L5 f# d. d) [1 d* \/ R1 d
  407.         CE_Low();                                /* enable device */
    ( w7 D; x$ i+ l
  408.         Send_Byte(0x06);                /* send WREN command */. ]: V2 z: Y! o1 \, l3 {
  409.         CE_High();                                /* disable device */
    2 a" N0 }! B/ T9 H
  410. }3 S# {. X) n+ Z* `" U
  411. . s8 {/ Y1 h- r' t  v
  412. /************************************************************************/' a5 b$ U7 A, L; R4 }3 m$ c( g- |
  413. /* PROCEDURE: WRDI                                                                                                                */. m6 t1 w/ K7 C; p( n% m4 U
  414. /*                                                                                                                                                */
    2 }# l: a5 R( ~
  415. /* This procedure disables the Write Enable Latch.                                                */
    * E; Z. z3 v# Z. p1 ?
  416. /*                                                                                                                                                */
    * A1 J: p* [- ]% F7 l8 q
  417. /* Input:                                                                                                                                */0 ], |4 F) N/ ~+ N  Q/ G' e- L3 X
  418. /*                None                                                                                                                        */
    6 o# R$ b: g5 ?) y6 B' y2 W8 v
  419. /*                                                                                                                                                */: L) N0 J% S+ @
  420. /* Returns:                                                                                                                                */
    4 e4 t+ N$ V. j% S
  421. /*                Nothing                                                                                                                        */# J# G3 w7 d# x0 P" v
  422. /************************************************************************/
    1 e1 `, `7 u8 \1 A% P1 l  g5 q
  423. void WRDI()
    ' ^1 M/ P+ L% L! P7 Z
  424. {
    * l& w# X1 O4 k, A/ _0 ]6 `
  425.         CE_Low();                                /* enable device */
    & S4 U- g' Y" |( f* a( s
  426.         Send_Byte(0x04);                /* send WRDI command */
    . t* l7 w# N* p
  427.         CE_High();                                /* disable device */
    ; i. M, m0 c7 s1 @/ q( s+ y- r- s. o( q
  428. }
    ! g2 _$ E- i' o3 l$ [/ }8 q! j* ?/ f

  429. ) l4 {4 H" J  p0 l6 W. z0 e/ c' ?
  430. /************************************************************************/* {9 X/ r' B" [5 V( K
  431. /* PROCEDURE: EBSY                                                                                                                */( G: O; H9 y) U
  432. /*                                                                                                                                                */
    " \8 i# y# S# g( i" `$ ~& W6 ^; e
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
    8 n. W# P! v" L$ v$ ^) s2 f/ `  F
  434. /* programming.                                                                                                                        */4 U, C' r# F: y% A4 _' V) a' i
  435. /*                                                                                                                                                */1 J" u& D! z" L& z) J; {
  436. /* Input:                                                                                                                                */
    ; ^/ }5 u! k0 J
  437. /*                None                                                                                                                        */' U' X# Y: `+ ]% \& z1 W- h6 _
  438. /*                                                                                                                                                */0 Z/ t: c$ O4 Q; v
  439. /* Returns:                                                                                                                                */  f$ s, M/ I& t6 N3 m0 Z
  440. /*                Nothing                                                                                                                        */7 l7 s* D! [- S! F
  441. /************************************************************************/
    3 G$ W* T; B; `! w; Y& ^6 ^
  442. void EBSY()
    . C# ^5 p" ?4 R/ x! I3 h# d
  443. {
    9 @; t1 {8 E3 |
  444.         CE_Low();                                /* enable device */
    0 I! E0 a0 y: s) O
  445.         Send_Byte(0x70);                /* send EBSY command */# m1 n) k! ]5 Z& b. }# s% }, v
  446.         CE_High();                                /* disable device */
    # l' I2 X* l; u) ]1 I9 ?# a; A
  447. }( ^1 J" d1 v# {# Y
  448. ' N! u8 ]/ @& l4 ?  E" j% L9 G% Z
  449. /************************************************************************/$ d- l+ ^# j6 Q' \& \$ M
  450. /* PROCEDURE: DBSY                                                                                                                */0 t( L! Y# B! a5 t. i- w
  451. /*                                                                                                                                                */
    $ C7 X& n1 C. n* |5 o
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    ' B) ]7 m& |* a" n" I
  453. /* programming.                                                                                                                        */( r! e% a) v. ]6 T5 E# T4 k
  454. /*                                                                                                                                                */: O; i0 g1 @" j+ Z/ {4 a
  455. /* Input:                                                                                                                                */
    # |- _8 N. P* {1 ^  f  W0 ]/ D
  456. /*                None                                                                                                                        */# `8 v! W; m+ k& j2 P
  457. /*                                                                                                                                                */
    + z8 i! E4 i# D/ i4 P2 ^& D0 L  s0 Z
  458. /* Returns:                                                                                                                                */
    : q1 M/ m1 k) ~5 @
  459. /*                Nothing                                                                                                                        */
    + f$ F  J  D5 S
  460. /************************************************************************/
      l4 R$ i, ]! b, `7 F* y0 d- N
  461. void DBSY()  a$ p8 X+ h% a& Y. q* A
  462. {
    1 C( N, ?8 b5 s( T  a
  463.         CE_Low();                                /* enable device */
    4 L5 H7 |' ^2 M' o+ U* B
  464.         Send_Byte(0x80);                /* send DBSY command */
      K4 I1 c7 `7 C2 ?$ F1 Q# H
  465.         CE_High();                                /* disable device */, |8 i1 Q) |+ ?4 d
  466. }. s- G6 E6 C2 F
  467. , }  ^! t1 p' w
  468. /************************************************************************/5 d5 y* a  t  D! s/ _
  469. /* PROCEDURE: Read_ID                                                                                                        */; m* e: A( g! ?  @9 x( y- N& t4 z
  470. /*                                                                                                                                                */
    ; Y9 r/ y* h. Q. J
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    ! z0 r) M; ~& U
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */% b( c4 r: ?- v9 g0 x2 d
  473. /* It is up to the user to give the last byte ID_addr to determine      */( z+ B2 g* I# H$ D6 ~1 u. ^: q3 K2 @
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    2 O; ]4 H; e/ U1 }1 |3 x
  475. /* first.  Please see the product datasheet for details.  Returns ID in *// W: v3 |0 z9 F; E6 C: C$ t
  476. /* variable byte.                                                                                                                */& Q2 e1 }( t& ?$ b% r5 D! _
  477. /*                                                                                                                                                */
    + Z0 }. @7 M- u5 f* r
  478. /* Input:                                                                                                                                */
    ( y8 t: I- M4 C5 [6 ]
  479. /*                ID_addr                                                                                                                        */
    ' `7 h- s6 Y+ t6 u6 j1 f8 Z
  480. /*                                                                                                                                                */9 A. A1 K1 R! W9 w7 X
  481. /* Returns:                                                                                                                                */' r* q. C. ^/ j4 ^' ~! h" X
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    + z% G) Y+ O1 O8 s  N
  483. /*                                                                                                                                                */3 L" [/ _" b+ `: t& t+ O) g
  484. /************************************************************************/
    ) r  S4 |& T/ O. `
  485. unsigned char Read_ID(ID_addr)
    6 d4 B' G4 r4 }* B3 D1 |# C
  486. {4 e8 X. k2 F1 t* ^
  487.         unsigned char byte;
    4 g& ^. a. }4 Z6 K
  488.         CE_Low();                                /* enable device */7 s6 P. p2 F9 I+ n
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    % m. O6 ]1 Q4 V% v# i
  490.     Send_Byte(0x00);                /* send address */; G  I- F. J/ I- k
  491.         Send_Byte(0x00);                /* send address */& @: H( }# Q9 o4 W
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */* L- R4 u& W* W# O" q+ ~& i9 j
  493.         byte = Get_Byte();                /* receive byte */
    9 m# r9 D5 v0 d
  494.         CE_High();                                /* disable device */
    4 n6 c: {4 b) S4 Z( d5 W6 t
  495.         return byte;
      U5 J6 ?/ B6 i: _
  496. }
    3 G6 z3 ?; u" D- w) o) z  _" m, K

  497. / |- o9 s$ O, r0 [! b
  498. /************************************************************************/  \1 M' Q; |' \) s0 M( m
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    + u7 u( [# s$ ?; t' l
  500. /*                                                                                                                                                */# X4 ?  O. g6 w6 d, a' _& N5 B
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */5 ^- P7 G% C4 Y/ w: T1 V: u
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            *// d1 E" {( A' F# p8 W9 w) q, M- U5 ]
  503. /* Please see the product datasheet for details.                                                  */* @+ W% T1 ]" ^9 D0 j- r9 H
  504. /*                                                                                                                                                */
    , V/ C# j6 U2 C( e6 C% d
  505. /* Input:                                                                                                                                */
    9 V- |: D0 ~2 s( o# q
  506. /*                None                                                                                                                        */
    * ^# J- D; g! c) _4 _
  507. /*                                                                                                                                                */
    - Y1 y- d* P! _; S# Z2 _- l$ \8 d) Z$ X
  508. /* Returns:                                                                                                                                */
    , V* F, Y/ X, |
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */& v( V7 \. i6 M+ C2 c% W6 B
  510. /*                 and Device ID (8Eh)                                                                                        */
    4 z/ l/ h7 M9 v) E
  511. /*                                                                                                                                                */2 m7 m( i" h% F% c# {
  512. /************************************************************************/5 K1 g! a0 x' V
  513. unsigned long Jedec_ID_Read() % @" p2 t3 G; D
  514. {% I' `9 z' S8 x- c1 f
  515.         unsigned long temp;: n: r7 v* F; H/ l1 `
  516.        
    & {& R9 J) {+ o( c
  517.         temp = 0;( j3 m6 W# g0 E3 ]! ~  E
  518.   C+ T+ H0 \( T* u, |! c
  519.         CE_Low();                                        /* enable device */
    + X( O5 a/ _$ n; B2 T4 n. B
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) *// c; o" ?5 K& u) k% M$ z2 O- v% O
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */
    ; Z0 z1 x! k5 [1 O) P5 ]
  522.         temp = (temp | Get_Byte()) << 8;       
    2 O5 c6 f6 N6 d7 f
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    4 X0 X, C. C4 Q9 x4 c
  524.         CE_High();                                                        /* disable device */
    5 w) `# {) }1 z: b
  525. ( R  V, z3 Q7 r" o1 m  ?' W$ Q6 i, C
  526.         return temp;
    - f1 N# ]0 D! I0 K: E- h, w+ g
  527. }
    4 _3 K7 g. C" g; l! y

  528. 4 J- \! G: N8 O* s! q2 o9 U( [4 ?
  529. /************************************************************************/
    , K3 j: z0 A! m
  530. /* PROCEDURE:        Read                                                                                                        */+ t6 i6 O, H+ v' B0 z0 Z0 E
  531. /*                                                                                                                                                */               
    / T0 X: B, u" @7 f9 E3 ]: g) ]# t
  532. /* This procedure reads one address of the device.  It will return the         */) d4 B% x, o- E0 m+ T0 U& j
  533. /* byte read in variable byte.                                                                                        */
    8 ^* q4 n4 D# o/ A3 f- ^
  534. /*                                                                                                                                                */( z5 \. U4 w% P3 z
  535. /*                                                                                                                                                */9 B) n. ~3 V+ P: S
  536. /*                                                                                                                                                */
    7 b  L; A! i0 P# P
  537. /* Input:                                                                                                                                */
    / `; D$ l; p; x: _$ y
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */% I- `! V" [' n. Q( F& B
  539. /*                                                                                                                                      */& n/ }0 O% ~4 |2 L5 n, Q2 }% k6 \
  540. /*                                                                                                                                                */
    7 V0 R& L9 x$ j. H# x
  541. /* Returns:                                                                                                                                */( u6 [/ d# A7 F" M# i2 ~
  542. /*                byte                                                                                                                        */' ]& }6 m6 j1 u0 s
  543. /*                                                                                                                                                */2 G& z2 k4 L- ~: q; T3 N- _
  544. /************************************************************************/
    ! I/ z" `4 |+ {
  545. unsigned char Read(unsigned long Dst)
    + e; j: Z# T4 {
  546. {9 h9 F8 ?" p3 j3 {! n2 t1 l
  547.         unsigned char byte = 0;        8 o) M3 [4 w% g: A
  548. 1 }$ F& F- h+ W3 G+ }! s
  549.         CE_Low();                                /* enable device */
    ! F. \- ^5 a  s+ E( D  w. n2 [7 f
  550.         Send_Byte(0x03);                 /* read command */
    % `' l0 m: ]4 [! v" u
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ) @, V; f- J3 o+ o
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));$ L4 s8 y& g# R. P. e% F9 [+ E( p
  553.         Send_Byte(Dst & 0xFF);+ o& E* K/ p# i
  554.         byte = Get_Byte();
    5 D- q+ c, m" u$ S3 o9 O! i
  555.         CE_High();                                /* disable device *// F9 d% |: c1 P$ y5 F+ ~
  556.         return byte;                        /* return one byte read */) t. B# k' z; s4 Q1 m9 m5 H
  557. }
    $ c5 t7 ?: b. s) m% r& G
  558. 6 W* C! l4 F2 U# L) ^0 g# P
  559. /************************************************************************/
    1 B# n, h% x4 {8 I
  560. /* PROCEDURE:        Read_Cont                                                                                                */* C$ Q8 j' n, S! ]4 U# p
  561. /*                                                                                                                                                */               
    6 c( w& N2 s' ^- Y- @
  562. /* This procedure reads multiple addresses of the device and stores                */: v( d8 q0 M# \- {( i2 _5 a6 A
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/! h7 w% q9 m$ U0 H. |
  564. /*                                                                                                                                                */
    " J) P" h4 v- ^: s% o
  565. /* Input:                                                                                                                                */% n( i6 Q2 n9 x' G1 }
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ! R  D: E: i$ P2 Q* f' ^
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */' K. k6 c# w; @3 F$ |( ~
  568. /*                                                                                                                                                */
    $ F) l- b8 C1 f! r9 o- a. a
  569. /* Returns:                                                                                                                                */( o6 f7 b% H" Y' c# e0 g" y
  570. /*                Nothing                                                                                                                        */
    . h7 h( r* s! ]2 {" T7 P
  571. /*                                                                                                                                                */
    . |0 [$ T  b: L
  572. /************************************************************************/: F: I4 o8 \/ O+ M: k
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    $ r" R9 u; ]2 h
  574. {$ r' ?' e) S9 @
  575.         unsigned long i = 0;
    $ u3 V6 l3 `; a  [3 B1 K9 t
  576.         CE_Low();                                        /* enable device */
    / m) X& }0 y& ^, H. s: g
  577.         Send_Byte(0x03);                         /* read command */% s3 ~8 L1 ^4 o! J" N
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */2 z* Y) d& j. T- k5 a  U1 X
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    . P' F7 W6 q- S5 o. Q! `6 V$ y1 Z
  580.         Send_Byte(Dst & 0xFF);8 a4 O, h6 ~: E
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
      C* ?! c$ W! b# c7 \& E
  582.         {
    . c5 L9 H2 H; ~3 G4 v
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */4 ^- }2 Y4 V8 ~' A0 R
  584.         }5 D; n0 q$ t: N' K- h
  585.         CE_High();                                        /* disable device */
    $ K9 G$ v+ D& e( l

  586. % E. M4 R( ~& H1 d% l( b
  587. }
      z, L" r; s& p" ]! U9 [
  588. & R0 L4 t% @8 `" m5 d! r. b: S* r7 M
  589. /************************************************************************/3 q# G  s/ M0 I% ~& i- d
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    # W# V1 a, O8 i) v% V
  591. /*                                                                                                                                                */               
    + `4 t! }% y9 B+ v% }
  592. /* This procedure reads one address of the device.  It will return the         */
    9 n- F+ e8 H; k. s+ f4 A' p
  593. /* byte read in variable byte.                                                                                        */" b) _/ J+ e% H3 e1 q' r
  594. /*                                                                                                                                                *// q9 p1 [6 ~3 N! |( {6 w' n
  595. /*                                                                                                                                                */
    ! f: L1 W' A2 M, Z: _  M
  596. /*                                                                                                                                                */
    ) o3 o( v' x2 q+ Y
  597. /* Input:                                                                                                                                */- D; D! i" G7 I0 |0 I5 ?4 T. u/ q
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    9 y3 v* w  x$ L8 x7 T" i% i
  599. /*                                                                                                                                      */" i7 `8 a$ h5 v5 g# i0 m: Z
  600. /*                                                                                                                                                */
    , z" S5 X2 K# `+ f( \/ Y2 j
  601. /* Returns:                                                                                                                                */6 o7 V) W# O& I( ^( [
  602. /*                byte                                                                                                                        */
    : P3 E( I7 c) p% R- {0 w
  603. /*                                                                                                                                                */
    ; ~; f% {( N: M6 |, B
  604. /************************************************************************/
    # e+ E6 t6 V( {) _1 ?3 a
  605. unsigned char HighSpeed_Read(unsigned long Dst) 1 W6 I' t0 N2 g  i2 u; v1 m1 Y6 a. c
  606. {
    , D$ D0 N+ G5 O+ e3 W$ v, ]
  607.         unsigned char byte = 0;        7 B! ]0 V5 T, q. n. Z+ F+ n
  608. * d# L) p5 v* f# K0 F
  609.         CE_Low();                                /* enable device */
    4 ]! \. I0 B  W; V6 s* C7 t
  610.         Send_Byte(0x0B);                 /* read command */5 M, A5 }9 z. y7 k* j% [1 ]3 f
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    , l0 p  z6 D/ C
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    : B  Q4 H' d- a# V
  613.         Send_Byte(Dst & 0xFF);, H$ n* M" \9 v7 d9 x
  614.         Send_Byte(0xFF);                /*dummy byte*/% d8 T  ^& m0 `: W0 Q$ J8 w
  615.         byte = Get_Byte();
    , h+ {2 K" d' n& t/ o2 Z8 |
  616.         CE_High();                                /* disable device */, @* ?7 Z. N: a9 v' C# T% y
  617.         return byte;                        /* return one byte read */
    $ b" q% T8 @/ y, G' n
  618. }
    0 |; N' H6 E: O* W0 g
  619. 0 B: y) `" C: \+ I. K
  620. /************************************************************************/
    7 [2 I" J2 L7 [5 p8 @# F
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */' \* \" U2 F8 j* }8 ^  W; ^
  622. /*                                                                                                                                                */               
    8 _6 S* o6 M7 k0 W  t$ w+ n
  623. /* This procedure reads multiple addresses of the device and stores                */
    * g' p3 d- A# o) H$ K
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/- M! K5 {3 \( C! }
  625. /*                                                                                                                                                */
    % G! {: O+ W3 S/ o+ X
  626. /* Input:                                                                                                                                */
    0 Q3 `& I7 |# _+ h& d% x
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    1 u! D) ]4 r. h. R) p
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */8 y( m" Z, u% Q% J7 i
  629. /*                                                                                                                                                */
    . f) T$ x9 a  E
  630. /* Returns:                                                                                                                                */
    6 p0 r( d& C9 u; L" n5 ~, c& V
  631. /*                Nothing                                                                                                                        */$ r7 t6 b$ B% C- X# z  O; t% R
  632. /*                                                                                                                                                */
    " b& w9 U7 c( Z
  633. /************************************************************************/' e9 o- y$ Q) K% T8 e3 _
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)& _" U) E+ R# B. d
  635. {
      _) W6 i2 v! q- l9 j& ^
  636.         unsigned long i = 0;
    ( T( S# A2 b' a# Z* f& i
  637.         CE_Low();                                        /* enable device */
    6 c' c8 D5 U& p& @: ]0 s/ ]. A! g
  638.         Send_Byte(0x0B);                         /* read command */4 |2 ]3 r. \) o5 y
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */3 P. o1 F  T7 E( D/ |  h
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));  @& @! D6 v5 M8 K0 v6 i: d! o1 C( i, u
  641.         Send_Byte(Dst & 0xFF);* \% K8 R) m  Y/ P' Z, F1 F
  642.         Send_Byte(0xFF);                        /*dummy byte*/. A$ Y3 D! m2 k% Q$ l
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */- R& k9 L( C" K$ y' q
  644.         {0 k% g, s- J( B' t  i' k
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */# H% ]6 F( N0 S: q6 O* v
  646.         }
    , ~3 T! Y' ]* V; l/ B) o
  647.         CE_High();                                /* disable device */. j3 I' [9 a$ a- u
  648. }9 t# Y  g8 c" D) J9 G
  649. 1 K& I1 o: G" ?0 R7 ^
  650. /************************************************************************/
    % d  v$ B2 f. y
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    0 a* x  ?- Y9 L
  652. /*                                                                                                                                                */3 \. e! t9 y( E6 ~: N
  653. /* This procedure programs one address of the device.                                        */8 A9 G2 k, m! X8 v# s
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    ) Q# g5 G0 l4 f2 p( X- X! u8 d
  655. /* block protected.                                                                                                                */& Q0 _* H& |% _
  656. /*                                                                                                                                                */
    - C1 `+ k% V- e! Z1 p
  657. /*                                                                                                                                                */; O1 T9 V" O2 j5 N, k
  658. /*                                                                                                                                                */7 K9 K6 T& s# J+ [9 Y- `( i6 ]+ b' |
  659. /* Input:                                                                                                                                */
    * P/ x) W$ k, N4 V0 |
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ! _6 @) h% _+ Z- m+ Q
  661. /*                byte:                byte to be programmed                                                                */
    ' {" a. B( ~( M4 \$ s
  662. /*                                                                                                                                      */
    6 }& x0 \+ r. y4 h
  663. /*                                                                                                                                                */5 A, c) ?+ c; t# M# N7 r' u
  664. /* Returns:                                                                                                                                */+ G. ?& x  {3 p: w
  665. /*                Nothing                                                                                                                        */8 H* R( z& ]- z4 Q
  666. /*                                                                                                                                                */$ n, u) V+ Z  _4 f
  667. /************************************************************************/1 f5 a; Q- A5 w9 t5 a
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    ! `, d& o$ t$ @8 A
  669. {3 Z7 i: i; A/ s" T4 x$ t# X. z5 F
  670.         CE_Low();                                        /* enable device */
    9 A/ D  _- ^. Z" Q$ A4 L
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    # e4 ~: O: m- [) m$ y4 d! ~
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    ' w) I9 c" y% u/ a. C
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));7 o" P4 b9 r1 z. V8 d" f) r7 Y
  674.         Send_Byte(Dst & 0xFF);
    $ W1 G' R0 M7 q" j! I: H3 u3 M* x* J
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    0 X& @7 I! P' \7 w2 v! U
  676.         CE_High();                                        /* disable device */0 V. A  u6 i: m: S( w
  677. }+ ]! t4 l& @1 [; d
  678. 3 j  o. ]0 e6 I& o* [$ b
  679. /************************************************************************/$ @& W+ a9 F$ v
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */% {9 u1 P6 v4 Z) q, R. O$ v
  681. /*                                                                                                                                                */
    ( ?# l- C$ c" _2 ~+ L
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    8 [) W+ b  I; r4 z
  683. /* the device:  1st data byte will be programmed into the initial                 */
    1 e3 k8 P$ F! g( s
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    / I, o# I8 T1 O% _! ?" h9 Z$ h
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    . y! Y1 h7 C, u
  686. /* is used to to start the AAI process.  It should be followed by                 */
    1 s9 N. u, v/ f
  687. /* Auto_Add_IncB.                                                                                                                */
    . n$ z: g( S) W6 Z3 ]* }/ K2 w
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    : _) d/ ?9 f* y7 h- d& }
  689. /*                                block protected.                                                                                */% a! S: Z  K5 h8 F0 t
  690. /*                                                                                                                                                */
    6 y9 q. ~4 Z- ?
  691. /*                                                                                                                                                */
    ) I0 D7 D4 R& ~+ z* a& L
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    % a4 t3 z: Y& @3 v
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    0 y" T+ x& K, j+ A4 q
  694. /*         unless AAI is programming the last address or last address of                */
    $ o7 z! ]# a6 E& |
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    + \: L) t. {$ r! x
  696. /*                                                                                                                                                */
    1 E% k+ }* v# ~. X$ e
  697. /* Input:                                                                                                                                */
    3 W8 X/ V9 u; c* n2 [+ u( O& o
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */9 R! @/ [. P  z! J; ?# o5 ?
  699. /*                byte1:                1st byte to be programmed                                                        */
    0 z4 i3 s; D1 V; V7 l6 L2 d
  700. /*      byte1:                2nd byte to be programmed                                                        */
    5 A5 c% _% l9 r0 p. k3 q
  701. /*                                                                                                                                                */8 X; ^, k8 p7 }% s
  702. /* Returns:                                                                                                                                */
    6 u2 N  R2 F0 i, m
  703. /*                Nothing                                                                                                                        */- p/ t; c/ v3 l( m; [3 g# @
  704. /*                                                                                                                                                */
    # }7 P9 f1 `  }" _; `" E
  705. /************************************************************************/
    3 R. n0 ]. D! _, _- d( w. k, _
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)& J+ }( i  j6 A) p
  707. {
    # i$ g* M8 J7 a$ x$ g" T
  708.         CE_Low();                                        /* enable device */& p; ]2 M! M3 l' @0 R( H
  709.         Send_Byte(0xAD);                        /* send AAI command */& Q+ Y# s! j8 W; F
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */' P5 |  |4 H! [. {# Y' z, C
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));0 R7 r4 X8 ~$ V$ m$ ]
  712.         Send_Byte(Dst & 0xFF);
    % |6 z9 {; \, ], x5 M2 Y' m9 I- ]. g
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        0 R/ m  e* h* U- P
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */7 w8 [* h& G& Q+ z( P5 y, {4 E
  715.         CE_High();                                        /* disable device */
    1 Q' q2 e" R- |- y3 g8 C
  716. }* ]6 t' N7 j5 Y: [& H+ j# \3 T
  717. 0 |' F. y, @* Z* a' f
  718. /************************************************************************/
    ) V: x# K* E. }" f
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */% \! e! p6 x6 n7 a& X; A2 a+ p( E
  720. /*                                                                                                                                                */, I  E9 R" p$ Z4 I: l3 m8 n
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/, ^  a9 b6 u* L; D
  722. /* the device:  1st data byte will be programmed into the initial                 */5 P  i3 z5 [6 Y6 @9 [0 T: D
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    8 H3 W) G" v4 B& d. v
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    6 X1 _- S8 H0 s4 V% n. F
  725. /* is used after Auto_Address_IncA.                                                                                */
    4 K3 B6 p9 V5 G% {
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    8 O7 j# H$ ?+ _& a* b9 k; U
  727. /*                                block protected.                                                                                */+ O( b% E, Z" g, [/ X& m
  728. /*                                                                                                                                                */
    2 b% ?  W5 f3 ~0 v1 [, a" y
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */$ F; n5 J" g, C4 A3 q$ A  w# p
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */- {/ |% Q7 H$ \1 Y
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */: M  L% a% W- i" u- L& r4 J
  732. /*          to exit AAI mode unless AAI is programming the last address or                */" ^; H9 ^( p/ ?5 b
  733. /*         last address of unprotected block, which automatically exits                 */
    9 G6 ~7 X- V+ Q/ J6 s, _! Z* _
  734. /*         AAI mode.                                                                                                                        */+ a% Q$ v. U! g! M
  735. /*                                                                                                                                                */6 L/ z9 j2 P8 j* C
  736. /* Input:                                                                                                                                */* [( v" Z$ P: k+ k; s  S
  737. /*                                                                                                                                                */
    $ |* g% C4 u" A4 w. e3 t
  738. /*                byte1:                1st byte to be programmed                                                        */
    8 I* U- w% U1 \" s/ N9 o
  739. /*                byte2:                2nd byte to be programmed                                                        */" [' l! s9 B; d* t; g: ]
  740. /*                                                                                                                                      */
    9 W; Z/ `( b6 B3 O; R. E7 h* C
  741. /*                                                                                                                                                */
    5 i- }' R) ?) C% {
  742. /* Returns:                                                                                                                                */
    - k' B& I" ?/ X
  743. /*                Nothing                                                                                                                        */  q. G; G& q. U0 q
  744. /*                                                                                                                                                */8 h! t# D) G$ l  |; h  S7 x" R7 @
  745. /************************************************************************/; B  m$ i4 z& q/ `5 q. K; f% u" f
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)) f0 D, s+ v2 l1 `; M8 j; {
  747. {/ \0 l! x8 f# y. B+ X+ Q. i
  748.         CE_Low();                                        /* enable device */
    9 g" G7 h) S. b) j3 @% g
  749.         Send_Byte(0xAD);                        /* send AAI command */7 ~3 e1 H' p& K$ `9 i0 T' R  a9 u  H
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    4 [6 z% C" {, n4 G( k* R
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    / V& `- s! _+ Q, i- z0 Z2 B
  752.         CE_High();                                        /* disable device */3 x, T. V" u) Z1 q8 ~
  753. }9 h( u* B8 S  g
  754. ; m3 D! f% ]- t- ^2 W
  755. /************************************************************************/  b" Z0 Y8 x% G; U
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    * l+ _' f. R) ~5 Q' |% n9 U
  757. /*                                                                                                                                                */
    ) x& L- i8 y" Q' s
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */4 q" o( J/ h& U  Q* {$ @' _' T
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    3 H+ _  }; y+ A/ U- `) s' t
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    : P7 z' `/ R  L3 s
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    & j6 R/ u! l- i/ E
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    6 q: u/ t. }  n1 J$ B9 v5 Y
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    ( h. x; @+ j: l, Q& j& m1 M" j
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
    % H4 X1 [  J& Y1 z
  765. /* Assumption:  Address being programmed is already erased and is NOT        */: c' J6 D. {5 s5 U2 U
  766. /*                                block protected.                                                                                */
    3 K5 r4 G4 ]3 T' d
  767. /*                                                                                                                                                */
    ) b& k" b- s. c/ q7 I# G( Y
  768. /*                                                                                                                                                */2 t! n- G! p/ [: b
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */: W/ ^  _) H. M* `
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    + ~  V5 `. t' Q: s0 ]' S& g
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */4 ?1 v3 h* w9 g# }5 {- e6 s
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    / U* j+ Y3 V/ u1 P+ Q( J' P
  773. /*         last address of unprotected block, which automatically exits                 */: O" @$ E+ x( p% t) e+ j
  774. /*         AAI mode.                                                                                                                        */
    ) ?( \  I) D) G) E
  775. /*                                                                                                                                                */
    ( o3 O( r# J2 m% [! q* }8 _
  776. /* Input:                                                                                                                                */
    4 V8 B/ `: s5 g' p' a2 p
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */* b  y8 y0 n( V$ `
  778. /*                byte1:                1st byte to be programmed                                                        */, u) j# [# d! A0 v9 S9 H9 j, w+ a
  779. /*      byte1:                2nd byte to be programmed                                                        */$ y; U' Q9 P  d6 `! ]2 n
  780. /*                                                                                                                                                */
    $ R: k; e6 _2 Z3 m2 v. K/ K6 c& R
  781. /* Returns:                                                                                                                                */3 w& `5 O5 @. U/ b" W9 A
  782. /*                Nothing                                                                                                                        */: }1 I8 \' F" Q
  783. /*                                                                                                                                                */
    3 u& P6 p+ c2 K% y% z3 Y  G
  784. /************************************************************************/( c$ Y5 `/ B( E& |
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)7 O+ [8 d; R/ d$ q& y5 F1 B
  786. {
    & ~) F& Y5 O  K
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        - v$ O# v' _- o6 d8 o, U# j; ^

  788. 5 z% R- u2 @! O' o
  789.         CE_Low();                                        /* enable device */1 w% ~  U& K- F2 M- K1 d2 o
  790.         Send_Byte(0xAD);                        /* send AAI command */
    / G$ S7 _% A. f+ A: O' r0 F, n
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */2 Z& B8 A0 v+ m* }- Y
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));8 e5 K; N& S) n1 M- `9 A* G1 g7 M
  793.         Send_Byte(Dst & 0xFF);  v6 L; f. l$ ^% @7 a" E0 Q
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    : F% N, V; j3 `
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */- \/ U1 \) S* v  ?
  796.         CE_High();                                        /* disable device */
    / @0 J" b$ G# @; G+ `
  797.         # h' `  v5 r4 C& x; J( \
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */1 |" R3 n8 X: l2 ]" \9 g

  799. 6 E& @$ z" A* e/ K
  800. }; L: h% M' F" D, p9 \

  801. : `3 M* e' U1 Q# X3 w8 X5 y9 L9 u+ _
  802. /************************************************************************/) W# j( B! l3 K) e' C/ ^+ u3 D6 G4 e
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */" N% x! [0 w' m, Z
  804. /*                                                                                                                                                */
    * u! y0 Q" P* x3 p) K7 Y# Z
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    4 F9 ^% p( Y$ P5 ?% z" q# m
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    - g- ]! @" f5 O/ d
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    " q$ x4 i* w: i; N6 u! k: t
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    # l6 M0 H$ w5 @2 F3 v" a
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */; ~; s% F4 V$ R% p/ X  b6 C
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */4 ~. P& A# r4 ~0 @" F
  811. /* used after Auto_Address_IncA.                                                                                */
    0 N1 L7 t& m9 y( _
  812. /* Assumption:  Address being programmed is already erased and is NOT        */0 F! V& H+ [" R+ P! {5 j
  813. /*                                block protected.                                                                                */
    . F1 x: j" k9 b' p; K* Q9 q
  814. /*                                                                                                                                                */
    * T+ e5 p9 }  d+ [
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */9 P/ \6 \( a. K5 Z( B' i( F
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */! i( U1 b+ O* E- f( B
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */, U$ i/ a) l% w$ M0 ]$ z: w
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    - c5 ~( G0 X, W: o! i8 h% e
  819. /*         last address of unprotected block, which automatically exits                 */. _8 s1 s0 A8 \% g/ ]2 ^; ]# y7 w
  820. /*         AAI mode.                                                                                                                        */
    % W3 L9 I) u% {" v. [: T
  821. /*                                                                                                                                                */
    / h% O! u+ ^: A
  822. /* Input:                                                                                                                                */; x# ^. j. Z! Z  K1 u0 n1 x, u1 z
  823. /*                                                                                                                                                */
    , m" j* F) v# X& b- d
  824. /*                byte1:                1st byte to be programmed                                                        */, S0 t8 M% w# e' X+ }2 o
  825. /*                byte2:                2nd byte to be programmed                                                        */
    % u& U3 ?% t: j0 z7 m& \& [! n
  826. /*                                                                                                                                      */! @& ^- I. B0 G" {* m$ {
  827. /*                                                                                                                                                */" b) d' c. l- W" m  A
  828. /* Returns:                                                                                                                                */
    ( |/ m; E! B0 G* }) r/ A* J
  829. /*                Nothing                                                                                                                        */) Z7 X( R3 }7 @, \' X1 o" F* [
  830. /*                                                                                                                                                */
    5 w! K  n+ m# e4 M: r
  831. /************************************************************************/# w' W0 r/ {3 J
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)( ?& }4 [0 \' S! T
  833. {
    ' Q! X+ u+ B2 F: G
  834.         CE_Low();                                /* enable device */
    ! E, [; C+ ~; P4 H
  835.         Send_Byte(0xAD);                /* send AAI command */
    4 e4 I+ R9 X$ a+ \
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    3 X3 q& ~9 Z% m& [1 R! ^/ I: V
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    6 X% q4 D; o; j2 X
  838.         CE_High();                                /* disable device */
    . M3 Y) {/ Z& |  h
  839. 0 ~4 b' Q' k- ^$ a1 y
  840.         Poll_SO();                                /* polls RY/BY# using SO line */8 q" @4 Z8 G- s4 G% ^+ l: Y8 b
  841. $ \9 C! I' E0 d" y+ q
  842.         WRDI();                                 /* Exit AAI before executing DBSY */7 C4 j- O6 g: W% i2 P
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */! N0 X, w5 i$ R
  844. }
    2 j4 K1 O6 |7 W6 J

  845. ; v0 V  ?% r) ]. h& ^3 o9 i' \
  846. /************************************************************************// A3 c+ D; U7 \3 c3 T
  847. /* PROCEDURE: Chip_Erase                                                                                                */2 M( V8 m, p0 t) H. Z( r
  848. /*                                                                                                                                                */9 R- Q0 E+ {0 S3 O3 K/ |: h4 g
  849. /* This procedure erases the entire Chip.                                                                */
    , Q, m0 G& o: S( [: B$ J
  850. /*                                                                                                                                                */
    8 @1 s5 L" k1 V( n
  851. /* Input:                                                                                                                                */. u: H1 D" @2 s2 ?- @* ]
  852. /*                None                                                                                                                        */
    3 W" j' `5 b; B0 X: ~
  853. /*                                                                                                                                                *// L: X2 m. B0 s! _
  854. /* Returns:                                                                                                                                */1 U6 }$ S; ]0 ]+ \+ f% `2 L
  855. /*                Nothing                                                                                                                        */7 ?- ?6 X3 W8 q$ j2 f# `
  856. /************************************************************************/
    ; H5 e- [  F% P' Z% r! U& T
  857. void Chip_Erase()
    7 {. F* L- k  E% U# V# W
  858. {                                               
    ( [7 ?! j' b5 g' ]* z# e- a$ ]/ m
  859.         CE_Low();                                /* enable device */" Q, X: }6 s- d: |+ b- d
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */5 D" Z- }( X+ i2 g; v  r) ~& S
  861.         CE_High();                                /* disable device */# i( D6 c3 C+ w4 B
  862. }
      L# h3 X/ D1 H* f; e( q/ p
  863. & w: b) L0 ?6 q5 c- F" o
  864. /************************************************************************/
    ! x% J- \5 Z3 k. H% U
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    " ]1 w% b$ ]# V* N1 k" k3 p; Q0 X4 e
  866. /*                                                                                                                                                */4 j5 F8 P1 _! @# C
  867. /* This procedure Sector Erases the Chip.                                                                */
    2 W/ {5 g8 e5 j/ Z5 J+ O
  868. /*                                                                                                                                                */  `1 x. i! b% k, _3 q$ E
  869. /* Input:                                                                                                                                */
    ; Q% x1 j7 }7 f2 L
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    , C, k& h- o' R9 Y8 H/ K
  871. /*                                                                                                                                                */
    * j: `6 c$ e$ N9 N: O7 |
  872. /* Returns:                                                                                                                                */6 i, Z1 t. r6 W
  873. /*                Nothing                                                                                                                        */
    ; ^! ^$ h  \! i" K: ]
  874. /************************************************************************/9 a# o6 c! @! V3 Q9 \; d6 }* p
  875. void Sector_Erase(unsigned long Dst)9 w, z4 G' k! H4 h' `0 g4 D
  876. {
    ( i- g9 S, ^! s- }8 Q& U% g8 c

  877. ) @, A4 n* Q: _8 s# U+ H* u
  878. + M9 V* k! E, ?+ _2 W, a2 c
  879.         CE_Low();                                        /* enable device */8 s0 r  D" N, F2 Q  `& ^0 @- e
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    , g/ t5 i4 X8 P# c2 I" R1 Z
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */5 u& w( ?1 Q; g3 {0 }$ L9 G, s! F
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));' v" N/ M$ P' [& y8 R& P
  883.         Send_Byte(Dst & 0xFF);  y5 w  N4 T/ o. E/ z9 T
  884.         CE_High();                                        /* disable device */2 h% f0 F: @( f0 x8 p7 L
  885. }       
    + p7 q) h0 A: q% _

  886. # W" b/ R* c# \) g0 m0 Q( L  e
  887. /************************************************************************/
    , O2 I- t' l" x/ c
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */# N$ f0 _! n  b* ^; D
  889. /*                                                                                                                                                */
    0 A, b- m7 [4 t7 h" Y' b) I+ B. j
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */1 Z; Y+ H5 Q( x3 v0 J
  891. /*                                                                                                                                                */* ^* N/ k! z0 R6 ]% o: D
  892. /* Input:                                                                                                                                */; v& Y( v% I1 }" n. F0 f0 w: ]. ?
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    9 a! P8 E* J+ o, n0 u8 S
  894. /*                                                                                                                                                */
    0 Y' c$ T) u! |/ P6 E
  895. /* Returns:                                                                                                                                */
    * }7 F7 P: I  T5 \5 p
  896. /*                Nothing                                                                                                                        */
    8 K1 {/ g  {9 s) V0 x; C
  897. /************************************************************************/, P( ^) o0 M/ e" J5 X: W
  898. void Block_Erase_32K(unsigned long Dst)
    ; \; A+ r1 V& ?
  899. {0 L& S$ Q* T2 |* H
  900.         CE_Low();                                        /* enable device */
    2 i* _5 r% }/ S, N1 I+ e
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    5 B/ E% {  N, G" n# V: @0 x- A
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */! X2 c$ s7 q4 I1 O
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));! m9 [: |! D  g% M; o% b8 m
  904.         Send_Byte(Dst & 0xFF);
    ; _! n2 F# s- m; F& x
  905.         CE_High();                                        /* disable device */
    9 q& Z, {9 Q. E  u: J6 ~1 Y
  906. }+ U% G8 J, c7 G/ f

  907. ; b5 O% o& v; a$ i/ A- D
  908. /************************************************************************// f* ~7 l0 j( }: O0 l
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    : Y3 j* S& q  G
  910. /*                                                                                                                                                */+ y; l1 R' T1 w3 C+ d
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */5 |; N$ v' O1 N, `$ @) O
  912. /*                                                                                                                                                */
    8 u6 ^0 A3 E! r, H
  913. /* Input:                                                                                                                                */
    : g& z1 Y/ z; x# J: u$ U
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    5 Q, [, c, \6 ~- ^/ x7 E3 h
  915. /*                                                                                                                                                */) s% J7 O9 F: a
  916. /* Returns:                                                                                                                                */
    . u7 @6 A# @5 Y8 Q
  917. /*                Nothing                                                                                                                        */8 O3 D/ _8 Q/ g0 i
  918. /************************************************************************/1 I/ q0 S- {7 A, _6 a
  919. void Block_Erase_64K(unsigned long Dst): R8 R9 y. u' x  T4 C1 g
  920. {
    % b% t/ \, q; S- g" O1 e
  921.         CE_Low();                                        /* enable device */5 v! G! [- c" ]$ N$ N& h. U. k0 f
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */0 D4 T  D& k' \9 s" N/ R
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    3 i, a* H  Y; }
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    + ?9 E) b4 B1 Y. i$ t
  925.         Send_Byte(Dst & 0xFF);' e" _. w! r1 _4 T
  926.         CE_High();                                        /* disable device */' \1 \9 o7 A0 X* ~7 K
  927. }3 t) ~( Q0 i* ]4 K1 c# L, J, \  V

  928. , S# b( P: }3 J( x( G
  929. /************************************************************************/% I. g6 u# O* n6 k% `9 `, |2 ~# G
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    1 L! D# o; {" Q
  931. /*                                                                                                                                                */1 a9 _9 c4 t1 ~: E: \: E4 w% v, K3 h
  932. /* This procedure waits until device is no longer busy (can be used by        */) N7 \+ `9 f1 H$ j. d
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    6 E& n5 x) ^6 p: A8 a
  934. /*                                                                                                                                                */
    & b; J3 ~9 K- X" Q- i
  935. /* Input:                                                                                                                                */% B7 S" x- k% e! C; X; z
  936. /*                None                                                                                                                        */
    . q% T% I# y; ~$ S- p- [1 f
  937. /*                                                                                                                                                */) t' d6 e: n2 C5 p/ W
  938. /* Returns:                                                                                                                                */( ~5 {5 s3 `3 V+ f3 G+ j
  939. /*                Nothing                                                                                                                        */
    : }+ S" l3 P' i' I3 k
  940. /************************************************************************/7 `9 S) C* Q/ Q1 ?* j. ^: k
  941. void Wait_Busy(), d+ K5 M% O2 d9 L& R
  942. {7 q$ a! V2 q6 n- f
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    ' {  t& d8 d1 H* t
  944.                 Read_Status_Register();
    4 M2 k4 e8 I5 j( U! w; \! R
  945. }
    - N; F" N+ w! d( s9 U  h0 |

  946. 7 e5 _5 D+ z0 {: R7 b
  947. /************************************************************************/
      \7 Z% e* K4 |$ P- n6 S
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */2 ?3 Z, q8 k* o& c) b! n- L
  949. /*                                                                                                                                                */
    1 T* T- G3 Y* ]: Z- E
  950. /* This procedure waits until device is no longer busy for AAI mode.        */3 C/ Q4 Z) R- N5 U, @. O
  951. /*                                                                                                                                                */
    ; f* m. A9 C. t* X
  952. /* Input:                                                                                                                                */
    / A; V$ F; j0 W  j  M* S
  953. /*                None                                                                                                                        */& N3 l, l4 y& Y' E: A
  954. /*                                                                                                                                                */  g/ j2 Q$ \8 l- b) v# E
  955. /* Returns:                                                                                                                                */* G9 b$ C8 G' |) O6 y
  956. /*                Nothing                                                                                                                        */& v+ E- P* ?; s0 R% A/ `, n
  957. /************************************************************************/  _1 S/ ^% K0 j4 N2 u4 ~- J
  958. void Wait_Busy_AAI()7 R( ^1 E' d/ a# i
  959. {" y& U3 p' J; T. l
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    ) Q0 v! K# ]+ U- x7 h! n. v4 _
  961.                 Read_Status_Register();* Z9 m$ J0 G9 `! T
  962. }
    - r9 C; o4 ?# _& W/ C( v

  963. 3 D- q, j* }! b' c
  964. /************************************************************************/
    % L. }; D! @! x9 x- s5 S
  965. /* PROCEDURE: WREN_Check                                                                                                */
    : m$ h& R" F6 [' y) V
  966. /*                                                                                                                                                */
    * V0 n, l* _/ ]- y
  967. /* This procedure checks to see if WEL bit set before program/erase.        */7 S2 P- U/ S! ?& z
  968. /*                                                                                                                                                */
    8 z1 K0 e: C- I/ A1 x  i% E
  969. /* Input:                                                                                                                                */
    0 c3 Y8 i6 o3 k4 {
  970. /*                None                                                                                                                        */
    ) f$ G9 A! z8 O7 S. U* v
  971. /*                                                                                                                                                */
    9 a! f# t6 n! F7 |
  972. /* Returns:                                                                                                                                */$ U3 K2 \7 t8 j+ s: C" `
  973. /*                Nothing                                                                                                                        */
    8 B; G, U: F* ]
  974. /************************************************************************/" v4 s' w. U" L# R
  975. void WREN_Check()
      O: S  C. M7 g" V2 @, Z& d
  976. {, N2 ?) ^" O4 @% N! C
  977.         unsigned char byte;3 r8 r9 z* n. G. n
  978.         byte = Read_Status_Register();        /* read the status register */& ]4 H  h: r) S: f9 q
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    ; n5 v' }3 a6 n) {1 t
  980.         {# }7 e$ }4 F( Z3 h6 f% g0 S8 l
  981.                 while(1)
    : V! u+ r% J* `; z/ }- a- A
  982.                         /* add source code or statements for this file */2 h" P3 Y4 x+ P/ l8 H; K
  983.                         /* to compile                                  */* M' x6 `  r& i# g3 C" V# H
  984.                         /* i.e. option: insert a display to view error on LED? */
    7 N" f' H* c# Q/ q7 g& }7 D
  985.                  
    & G! N& E9 J9 E& c
  986.         }  w4 e+ Q8 }. C- `+ S
  987. }0 O; f+ w+ f7 I. e

  988. . f8 S3 f! L. c
  989. /************************************************************************/$ P% h. U" E7 F4 P% @
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */% m& r$ ?& {  Z. [% H8 j
  991. /*                                                                                                                                                */
    ; @7 f$ j& I& r( v0 q
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */1 |, @( U4 Y0 r. b. G1 b
  993. /*                                                                                                                                                */
    ! p1 d  i/ B, a; Z0 N# R  h4 _: `% O
  994. /* Input:                                                                                                                                */
    2 N& i* s( _7 A, ], M4 S$ p
  995. /*                None                                                                                                                        */1 d( j' l6 h# x
  996. /*                                                                                                                                                */! H4 {1 N* g4 \* M* y
  997. /* Returns:                                                                                                                                */2 W; u; z" K0 \
  998. /*                Nothing                                                                                                                        */
    . n* X, _* R$ G( z
  999. /************************************************************************/
    $ r* z: {% S: d0 D% i9 J% b( G! t- c  T
  1000. void WREN_AAI_Check()
    1 n" J! O5 y9 C( i/ z
  1001. {
    3 z  j0 g( E' T' Z2 ^3 d
  1002.         unsigned char byte;) E  y* A2 s8 _) L; U4 p
  1003.         byte = Read_Status_Register();        /* read the status register */7 @$ _  n& W, F% S* V. _  {' W
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    0 j) o% r+ Y* I: [( S" `% U- u
  1005.         {
    . P& b* s5 K* }
  1006.                 while(1)               
    " P2 j# C5 b- H8 Y% e) j
  1007.                         /* add source code or statements for this file */
    8 N9 ]5 c9 H# g8 {; l5 B1 S
  1008.                         /* to compile                                  *// ~3 J% r- X& B. W3 s
  1009.                         /* i.e. option: insert a display to view error on LED? */
    6 |6 A  L: s, L5 |" E! C# A
  1010. ; ~1 D- O, h( `6 r0 l0 x1 P& h& J
  1011.         }! v" y- l! X& N  `( p+ T6 S; z1 w. [
  1012. }
    7 w5 }  m, g) T4 j* f' l
  1013. 5 {+ q" R) d/ D6 l
  1014. /************************************************************************/  z: F( k# ]8 Q% ?6 w! ?
  1015. /* PROCEDURE: Verify                                                                                                        */2 n6 i, U$ n; J
  1016. /*                                                                                                                                                */  h5 s! |( I* N4 Q% l
  1017. /* This procedure checks to see if the correct byte has be read.                */
    ; C- F2 D, A3 v# e
  1018. /*                                                                                                                                                */" ?3 q' L6 |  Z) g6 g
  1019. /* Input:                                                                                                                                */3 F7 Y' ^" r1 J% D! C
  1020. /*                byte:                byte read                                                                                        */
    - `+ M. o# l! O
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    7 ~; L: \. f0 L# z) o3 Y: d- K
  1022. /*                                                                                                                                                */- Z6 a  q4 M! R, }- I# u$ U* v
  1023. /* Returns:                                                                                                                                */
    ! R& g! v: u6 W5 d" L
  1024. /*                Nothing                                                                                                                        */
    % [6 E5 w0 Y" G, g& e7 }, Y
  1025. /************************************************************************/! D1 `# z5 z) v3 m: h+ g& ^2 L" E
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    1 H( W" x; t  F1 j/ y
  1027. {
    / f- G; G6 e1 j4 J" }4 z
  1028.         if (byte != cor_byte)
    4 o- a. u! U- }; g- f
  1029.         {
      m- W+ c/ {- `6 U) b- D' ?
  1030.                 while(1)! d! A/ e; ?+ t$ [8 W. I% `
  1031.                         /* add source code or statement for this file */
    1 J" p3 H1 I6 K5 W1 t
  1032.                         /* to compile                                  */
    ) y) Z6 ^& W$ d. }# r
  1033.                         /* i.e. option: insert a display to view error on LED? */2 n0 i2 d( N+ x: \# Q+ |* C; \
  1034.                
    * X- h# Z3 I" \- |8 d1 [" {
  1035.         }/ U: O1 Q3 g* _4 H- @7 j
  1036. }( `/ N: n  a' x6 a
  1037. 0 s3 t- Y6 q2 P( S* Z
  1038. / e: A2 A9 z' J  Z# l" Q
  1039. int main(), O. k6 e$ K3 O2 h1 u
  1040. {' l* h( R7 e- u1 O' Q
  1041. / m7 w8 I- A/ M0 S. @
  1042. return 0;
    1 S9 f5 q; H/ q
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:& o2 |8 R1 V+ t
   main()
' D, K  E2 I( `8 Y9 B* ?; G   里面怎么是空的呢?2 ^: j- r* C2 X5 l* f8 A; q
   发一份给我吧7 g/ e$ t' N$ G
mail:luyijun2005@hotmail.com
6 O. k/ `8 Z2 q% O& x# [  R% |) p咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。
6 s9 f% f$ }4 A2 W+ f2 R- e/ v5 B+ L: t* R: l8 X, Y
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。: Q9 p- {, b, T' d; y& L' b2 K
EC的代码在哪跑,你看DS的说明,每个EC都不同的。* }" k9 D) U& k6 i, E( L8 C
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?/ o( n0 h3 e2 D3 F- D9 j
上面几个问题是你没看任何东西而白问。. w4 x$ N+ m) M/ b8 T" |0 ]3 u

( |- N' `+ S5 v: X  ^( \  }至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
4 D  a; @+ o; d8 p& G- k
  B+ q( V" L1 ]9 i: q& l6 \6 P关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!# k0 U  z* W; l4 K3 f

. E, b; s! r" {" X关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”
6 ^; z% W! v! d7 i/ n
8 u$ F. C! N* a) Q1 M) }/ A# C# W关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊..." [4 o. t! e4 x& u, u) }# D9 Q: o
- G9 ]+ X0 R+ |2 B  R7 U1 h
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
5 G0 i4 |6 Q; p0 u. S" M. m; l( [似乎要把SPI能support 到最大,这EC chip应该有好卖点$ K% k! ~1 J1 |. m; D' I
BIOS功能要不要强大,也就决定了SPI Flach的大小
5 S# N( P* {! @& @$ |' c" o我是这么想的~让OEM去决定要挂多大!
" h9 i7 T0 a# d- \( f1 S6 H5 m如果我司有BIOS工程师就好了~哈
$ N# F9 y# a' p/ h) MWPCE775应该算很新的东西,来看它支持到多大?
0 ]4 `& F) |9 O$ `, I! a: o! a8 j4 g  D2 ~' G! ~
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte- W! P/ x: p; j/ C: P) d3 _  ]
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.! y3 ?3 J, ~. P5 o( n  z7 Y
, B* x9 d& f0 t* A5 r. F
这份driver收下~希望以后有用到6 Y' D$ D3 Q) P% g8 z
谢谢bini大大8 R, E" S9 I5 O9 k

* w4 V. w! u* g& j( K' \* `9 C很新很新的新手,如有错误请指正 (准备看第二家的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()( f1 k3 i, T0 H1 C1 t
{3 i( p5 ]  X2 M5 K* h
        unsigned char temp = 0;
  U: D/ U' f& d. l+ k, n        CE_Low();$ K# n! Y: j. A, z: s" ]+ r
    while (temp == 0x00)        /* waste time until not busy */5 r% h  U$ A  ~4 W
                temp = SO;) ?* z" i$ r' t+ L
        CE_High();" q# C  t1 t; a  P
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)+ O9 j$ m' \9 [0 u
{, E3 W& e- D' `6 w9 y* m& e& O. u
        2 Z" \, C" m: ^+ d+ o
        unsigned char i = 0;6 B# h3 L5 Y9 q3 u
        for (i = 0; i < 8; i++)
; h. D' z& `2 |0 n) p8 Q4 K        {
! n) ~* j0 {! d9 l                ' e2 H* H; }7 w2 w5 D! N
                if ((out & 0x80) == 0x80)        /* check if MSB is high */
7 S! H% E8 n) x, ^- ^  O4 G                        SI = 1;- S# N3 W/ H4 y  ]
                else
4 B/ w) r, S: y: W7 s' g                        SI = 0;                                /* if not, set to low */
5 H$ Z9 N. W  u; d+ i% { 问              SCK = 1;                                /* toggle clock high */% b5 }* _; {2 p# n$ K+ l; J; E6 W2 J
   题            out = (out << 1);                /* shift 1 place for next bit */% S7 y# Z* R" T+ a- n
                SCK = 0;                                /* toggle clock low */
9 c+ [7 V1 b8 \0 T% e4 @7 o( N        }
7 \& E0 F! ?  A' x/ A+ h& r3 b# i}
) I# K( i+ G8 [( W 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-6-4 22:07 , Processed in 0.049147 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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