找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 54348|回复: 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. N8 c! [  `
  2. 3 W9 S# [7 x1 z% T0 g5 i9 V& t
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory& V% u& W7 o- I* Y; T
  4. " b' ?# I% A- S5 L
  5. November 4th, 2005, Rev. 1.0
    ! i3 l# ^' X% t5 Q
  6. ) z' b5 Y' z6 X+ B- @  Y
  7. ABOUT THE SOFTWARE
    ( Q2 W' N( \3 P
  8. This application note provides software driver examples for SST25VF080B,
    2 L) D; }# X) n" o0 M* k  R
  9. Serial Flash. Extensive comments are included in each routine to describe
    % D, m* }9 D7 @) Q& i0 T8 M
  10. the function of each routine.  The interface coding uses polling method * K5 l, X7 c; J4 p
  11. rather than the SPI protocol to interface with these serial devices.  The5 I+ H- a2 K1 ]- i+ u9 t9 ?9 w
  12. functions are differentiated below in terms of the communication protocols
    6 A& `, _) _" [5 b, `
  13. (uses Mode 0) and specific device operation instructions. This code has been
    9 \, g6 _9 F# n. I) O9 e
  14. designed to compile using the Keil compiler.. ~8 B; C5 n$ b' a$ q8 j

  15. & ?8 ^* b# Q% H& z4 _( a$ [
  16. ' J) F9 m1 S* J- |% Y4 n5 C
  17. ABOUT THE SST25VF080B
    + y0 l# O9 i( H' ]5 F! N' n

  18. ; W) `. h; w' [! W
  19. Companion product datasheets for the SST25VF080B should be reviewed in 3 V, F& }$ b9 q" z/ d* T
  20. conjunction with this application note for a complete understanding $ f# v* `0 C9 `: J; b1 A
  21. of the device.8 h8 q" S1 r; m7 |% N# b  b# Z
  22. ( s; m/ w  D; ?# ]
  23. 7 g; R: v' u/ H- T4 @8 ~+ X) q% C. X
  24. Device Communication Protocol(pinout related) functions:
    " o. G( G& |) _, Y% H3 j: s7 x

  25. / u4 v8 a7 X  n/ G; ^
  26. Functions                                    Function
    % g3 ]  I3 W+ r- X# u' M# I+ V( b: D
  27. ------------------------------------------------------------------; E1 f1 m5 G$ [$ f( ?
  28. init                                        Initializes clock to set up mode 0.9 Y! M/ ~- X; h
  29. Send_Byte                                Sends one byte using SI pin to send and
    5 {+ v9 h8 s+ U! X! f. A7 f6 @
  30.                                                 shift out 1-bit per clock rising edge' z! p: @( F% w6 X; f
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    : |" T$ h2 r, L5 P5 _
  32.                                                 in 1-bit per clock falling edge
    8 V2 L9 J8 {8 m  k* {& a- p
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    9 t0 ~$ c6 z% t8 R( v6 M
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    7 m3 O& h$ \! u. h- e% g9 J1 S: Z
  35. CE_Low                                        Clears Chip Enable of the serial flash to low7 r# E5 H- ?4 G0 @. Q
  36. Hold_Low                                Clears Hold pin to make serial flash hold' T$ A0 [; x# i. x( C% @- y* a
  37. Unhold                                        Unholds the serial flash6 r7 z/ @3 K- V3 G
  38. WP_Low                                        Clears WP pin to make serial flash write protected
    . C( M- n6 R- E% S4 y
  39. UnWP                                        Disables write protection pin
    * t  u; [* d: C3 p1 p" b5 w+ G
  40. + @. p8 b1 l: B& Y$ a( J1 _
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    ; {0 B- @: I2 K/ `- x6 P
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
    & q! {7 B& ^1 x+ N
  43. software which should reflect your hardware interfaced.          9 z% J* P$ m$ I
  44. 2 c* ?4 M* D1 U* e. D

  45. % T! `9 x% v  ~& q
  46. Device Operation Instruction functions:  G; K  d* f( O5 n! I% c3 h

  47. 5 b" i, E8 Z! M: U1 b$ x8 B
  48. Functions                                    Function
    * s/ R+ q* [2 R" M& T
  49. ------------------------------------------------------------------
    5 U, [! ^- G( e+ }: _! M
  50. Read_Status_Register        Reads the status register of the serial flash
    * n* y9 S! g4 M/ X# |, K
  51. EWSR                                        Enables the Write Status Register
    4 A4 U  {- p- Q6 a
  52. WRSR                                        Performs a write to the status register
    - h. m1 G: ^& l. a8 V
  53. WREN                                        Write enables the serial flash$ r) E, o' W1 y; [# z, ]
  54. WRDI                                        Write disables the serial flash+ o9 v3 W; G. I3 ~2 F' I
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming( |6 ^' ~# A4 z6 b- M4 x
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming7 {- c. V8 E! O
  57. Read_ID                                        Reads the manufacturer ID and device ID
    ( T4 a6 K& b% c
  58. Jedec_ID_Read                        Reads the Jedec ID3 j$ p( t( Q3 G6 o& r
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    9 |' k/ V9 Z; Z7 F+ l. \
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    , i' J/ W' p- l/ P
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)! f7 M5 u3 Q. o5 G6 }( q; i5 k
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)% y3 H- ?2 h) H
  63. Byte_Program                        Program one byte to the serial flash# h$ d. T( [3 y1 [3 R" g
  64. Auto_Add_IncA                        Initial Auto Address Increment process) @6 i+ ]8 W0 p( p& a; k" F( C
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    2 C1 M, w8 [$ O  r/ C, S
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY; O# B8 u, h1 w0 o; s% I; |
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY4 U% y. n; u  E  d
  68. Chip_Erase                                Erases entire serial flash9 X# B7 f, \' ^5 d* x5 O' h
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    - j4 O2 u  i1 Y* R4 F
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash7 _2 h8 t/ e' T. [' m4 h
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    5 U& G' l6 B2 z/ p, l
  72. Wait_Busy                                Polls status register until busy bit is low
    2 C& G3 r& Z* }; B! u) B
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    ' W6 [6 Z4 G; L
  74. WREN_Check                                Checks to see if WEL is set* P0 {& }' R1 m, k" Q, [) _3 c" c
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set2 I6 u) K; k8 Y/ t0 s! T( d
  76. 1 n/ F4 m- Y# t! y. g3 v
  77. 4 l& k$ l7 j) Z6 i$ C/ F2 z% l
  78. 8 a- H- {9 l" [
  79.                                                                      $ W: h) d% k$ l! c6 N
  80. "C" LANGUAGE DRIVERS 6 w. @0 [: L/ M7 I* p4 b. f

  81. ) j- o: ?. L2 q# ^& F$ K9 z! \$ a
  82. /********************************************************************/
    " m/ `/ M8 U; R; I1 m3 f5 g8 L- i
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    0 V% ~, d/ r: g: ]! i  w; M0 [
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    0 z# Q: ~1 t7 O$ o- C4 B
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    + ^. A9 R5 T% ^5 u5 x8 J
  86. /*                                                                  */
    . u# Q+ A$ f5 L3 H% y8 Q5 |! ~! _, |2 ?
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    5 r, v6 }# g- o$ L- t
  88. /*                                                                  */
    / K: ~1 y7 M! ?5 h
  89. /*                                                                                                                                        */! \* v" L  r3 X: k3 ^+ N2 q! J
  90. /********************************************************************/0 d5 I1 U3 \) J' e$ d( `
  91. - G) {' w2 C8 u- T3 t5 s5 v* }9 A
  92. #include <stdio.h>& L4 @5 S: J. p; J, _; n
  93. #include <stdlib.h>  E6 D. K9 q: @  y  \( E' v

  94. 4 v1 T2 s: T4 R; X
  95. /* Function Prototypes */  W2 p. G& l1 _) _4 L

  96. 1 m1 O: E( x  |, t
  97. void init();
    5 D+ k+ r  Q* [8 o7 u
  98. void Send_Byte(unsigned char out);' t! T. h" o; D5 m" }
  99. unsigned char Get_Byte();
    $ w0 h% o& p% R' A3 Z4 ~- s
  100. void Poll_SO();
    ' W/ e0 q: T/ w: l
  101. void CE_High();
    , a4 G/ x5 y/ M% v- B/ ?& f
  102. void CE_Low();
    . ^1 @. ^! N& `3 p
  103. void Hold_Low();( q! X, K% i$ M; ]& {
  104. void Unhold();
    8 o) d4 a# g! G9 \4 Y
  105. void WP_Low();
    2 }2 U' m( k% z/ q% l4 S
  106. void UnWP();
    # q+ Q- {1 G" h) U' w3 @
  107. unsigned char Read_Status_Register();
    / ~% a$ s1 Q+ O; q, C' ]% z
  108. void EWSR();9 T' {! R# y' a
  109. void WRSR(byte);  \; P6 B; w/ W$ f* }
  110. void WREN();# e! y' Y& F& D3 P: W& j
  111. void WRDI();0 Q* k* b$ l$ Q" n- E! C
  112. void EBSY();
    ' S0 ?% J4 R3 J! ?. h# L$ m
  113. void DBSY();3 v$ R+ p% _- ^% i3 P: U
  114. unsigned char Read_ID(ID_addr);+ @3 |, ?9 G! Q, R1 _$ t& o* ^
  115. unsigned long Jedec_ID_Read();   W1 ~+ M& F5 A
  116. unsigned char Read(unsigned long Dst);8 A4 a) ^( J* A+ j: S! |/ k$ t4 R
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
      i% `, Y  c7 E' b, s0 r+ T8 K
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    # ~( T1 l. p' z- ^
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);* Z" @) Y7 L3 n) d5 }0 m
  120. void Byte_Program(unsigned long Dst, unsigned char byte);& @% j  `: M6 J: `& W4 U
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    2 j/ p4 L* X. K' Z1 D0 p' @
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);( v; b/ b' s& s! F0 V+ L8 d% B
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    1 z* f1 ~% Z9 |& s1 Y
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    * o* I9 E) b6 f
  125. void Chip_Erase();3 x' s7 S- C  P/ x; S
  126. void Sector_Erase(unsigned long Dst);
    ! s$ [/ x" Z+ E) O$ N* s4 j
  127. void Block_Erase_32K(unsigned long Dst);0 T1 n3 ^& L: }1 L
  128. void Block_Erase_64K(unsigned long Dst);
    9 s% w1 L, \3 Z( @8 E
  129. void Wait_Busy();
    + h7 I" R( t- V) r2 Z$ m
  130. void Wait_Busy_AAI();
    ; ^1 }/ e1 S' ~( O4 h$ _! d' ?
  131. void WREN_Check();
    8 u: v0 m; z$ k3 {
  132. void WREN_AAI_Check();+ s1 R" J  R* R- x2 L# K8 }1 r
  133. * H. B" K, o. r; f
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    ' X  [. e9 s3 {/ X, Q. B

  135. ' F+ c/ X; g1 H4 F
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    % w2 v/ _2 d. r" \' U
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    4 u: I9 s' ]8 a" F( N7 h. \  v5 V

  138. ' I; E8 Q) V7 S
  139. /************************************************************************/
    / m+ p/ b' u7 s$ C5 D9 @
  140. /* PROCEDURE: init                                                                                                                */
    5 P+ i4 `2 u& [
  141. /*                                                                                                                                                */
    1 H3 d5 u& U; Y
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    ; T% H3 @; P( s/ w
  143. /* setting up mode 0.                                                                                                        */
    0 K  d! U% n2 @0 f2 Z+ k5 I) a
  144. /*                                                                                                                                                */
    * E, E# p" [- y9 i" _% U( A
  145. /* Input:                                                                                                                                */' Y7 ~! ^3 H6 v; t$ J
  146. /*                None                                                                                                                        */
    7 J6 _& A7 X. o0 H
  147. /*                                                                                                                                                */' _* ~& |5 L, V5 N( G! ]0 r
  148. /* Output:                                                                                                                                */6 K+ d8 Q& ~. G0 M# ~8 X
  149. /*                SCK                                                                                                                                */* f5 q* Y4 S  p* O& c: _
  150. /************************************************************************/- ?- E' T& g% w  {+ a* o
  151. void init()
    . `- k+ [9 H4 O. [
  152. {
    % i& z- J+ @3 u9 c! j+ ~  e  R
  153.         SCK = 0;        /* set clock to low initial state */
    * l8 P0 ?, i* a& I
  154. }1 h: z, m$ U; _4 J. j. t) J4 b
  155. 8 O" B( _3 x2 T  l$ L& U
  156. /************************************************************************/" i. @6 [* ^, h8 t
  157. /* PROCEDURE: Send_Byte                                                                                                        */3 }3 Z1 u9 V4 J+ I! N
  158. /*                                                                                                                                                */
    5 w7 q5 X$ o+ Z; g& x4 l
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */2 K* H6 U# ]' A6 l& @( A% O1 D
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    : D- U6 `$ B+ E+ W. f
  161. /*                                                                                                                                                */
    - @+ _* J4 _# |: B; i; w4 H0 G" U
  162. /* Input:                                                                                                                                */
    : {0 |9 h0 _- U
  163. /*                out                                                                                                                                */
    / Z- a9 W" M* g, U5 i
  164. /*                                                                                                                                                */. A$ G. Z$ t: f* o' }) t: o& v
  165. /* Output:                                                                                                                                */$ I7 G3 j1 L" u* _- G- y1 a) H
  166. /*                SI                                                                                                                                */
    ! c' }! v/ |- x" ~: @0 \8 j
  167. /************************************************************************/  i1 M1 ^- Z4 l+ c9 {4 G1 Q% \
  168. void Send_Byte(unsigned char out)- S& m% h  B* N, B
  169. {
    4 j$ s" V3 d* D1 g
  170.        
    ; J7 M/ A1 @" z* V) }5 e
  171.         unsigned char i = 0;. `) x' R/ }( z4 Q
  172.         for (i = 0; i < 8; i++)1 f% c4 M% |! d/ D
  173.         {' f8 p9 Y" l2 [" k- n: e: R0 W
  174.                
    ; Q! d2 E7 E2 J3 a/ t7 V
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */& W! F& T6 Y& ]8 z  T  D) d
  176.                         SI = 1;
    . d+ l2 Q5 t4 w3 W2 o0 c: {
  177.                 else
    : W! `4 O/ F9 ~( f1 C. R8 Z
  178.                         SI = 0;                                /* if not, set to low */
    5 d+ l7 @# {; v! P) q: i7 }5 r
  179.                 SCK = 1;                                /* toggle clock high */
    : M  j: M, W. H1 M% K1 W4 F1 Y
  180.                 out = (out << 1);                /* shift 1 place for next bit */' J# ^$ ]! P% R
  181.                 SCK = 0;                                /* toggle clock low *// P' ~/ m& k" i
  182.         }' t; J9 Q- T3 d' {3 P3 j8 d
  183. }
    ! E8 G  r/ b) D. P1 v7 I; u

  184. % X0 Y/ ]" c% {- |6 m
  185. /************************************************************************/6 f, y5 i6 j1 w# c- B0 k* S' f
  186. /* PROCEDURE: Get_Byte                                                                                                        */* p1 `2 \& \) S# m/ c
  187. /*                                                                                                                                                *// ~0 \  W' N7 z& g* L# c' O' w4 j2 Z
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    : z( v( r3 ^7 \9 w
  189. /* edge on the SO pin(LSB 1st).                                                                                        */2 G4 V7 N: F& E0 z9 ^
  190. /*                                                                                                                                                */6 j7 V+ U; ]2 T( ]0 w
  191. /* Input:                                                                                                                                */, I2 G6 o" {2 w. _8 J+ Q  p
  192. /*                SO                                                                                                                                */  Z5 @) e" U9 `& ^
  193. /*                                                                                                                                                */
    9 Y# p  ?) m' c9 N1 p
  194. /* Output:                                                                                                                                */
    5 O1 K" X( H4 h+ ^2 A( }
  195. /*                None                                                                                                                        *// }3 ~% k# Z5 a$ P* z, j" v
  196. /************************************************************************/
    ! D+ ^7 ^( _& \% i9 b1 o
  197. unsigned char Get_Byte(): K& [9 P" \: u* X1 x- K' O' p
  198. {- E( G" m) Q0 \, E) R+ ^0 p# h
  199.         unsigned char i = 0, in = 0, temp = 0;8 y" K" W- P) u; f% _
  200.         for (i = 0; i < 8; i++)2 N& T/ Z" b5 ^! N7 V
  201.         {
    * o) j$ n4 L! F3 W* T3 T; ?' [
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */  ^4 h" ^# ?1 \1 c3 ]3 F
  203.                 temp = SO;                        /* save input */( p8 Z% M, b$ G8 ?
  204.                 SCK = 1;                        /* toggle clock high */) x4 c7 D: D; Z# ?6 c. P
  205.                 if (temp == 1)                        /* check to see if bit is high */
    6 a6 [8 \/ F" H
  206.                         in = in | 0x01;                /* if high, make bit high */: y" w" }1 g4 K2 z/ b, v5 K. g  W

  207. - y( u" B" N7 w% a
  208.                 SCK = 0;                        /* toggle clock low */
    , n1 p. ]1 n% L" o# B9 H
  209. 1 V+ K% x, {* @) W, A+ `
  210.         }6 {' `3 _  K6 ?1 V% y* M
  211.         return in;9 Y7 ]" F, c3 q/ B' E
  212. }0 t# ]0 b# }7 ]- M) O  m. }
  213. ' S$ a$ V+ H/ q; Z
  214. /************************************************************************/. V, C' C5 m6 [! b5 e
  215. /* PROCEDURE: Poll_SO                                                                                                        */7 y% _% Q( ?8 l& h# d2 W# \/ [7 V
  216. /*                                                                                                                                                */: S, n" }* O, |. w' m( |: j! l
  217. /* This procedure polls for the SO line during AAI programming                  */9 ^& p" x, s, Q7 A" `/ ]
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/; m: d" h5 |$ B- F
  219. /* is completed                                                                                                                        */. s3 m9 u: `  G& Z+ q& Y& Q6 t/ x
  220. /*                                                                                                                                                */
    ' i: J' `  b, S5 p: ~0 q; P& m
  221. /* Input:                                                                                                                                */
    , @" k8 x: H& t: c* J% n% `7 q" J
  222. /*                SO                                                                                                                                */( g( e9 u% m+ _1 S! Q' i/ B* H4 U
  223. /*                                                                                                                                                */8 T1 X1 U/ k" p* j+ \+ u1 N! c' o
  224. /* Output:                                                                                                                                */
    # S$ d0 C/ e2 M2 T; Q  y
  225. /*                None                                                                                                                        */. E$ F4 [! X* |8 g$ M5 ]
  226. /************************************************************************/
    7 D; D$ _6 e8 O' v
  227. void Poll_SO()8 N" `, Z: q9 j) R" X
  228. {1 d& Q  R: J# ]+ M5 R" j
  229.         unsigned char temp = 0;1 C8 O) ^1 d4 e5 @
  230.         CE_Low();
    $ `+ }+ P0 p7 g& q+ t' g4 A& G
  231.     while (temp == 0x00)        /* waste time until not busy */
    ' x7 n* d& f! C# H! ]; u
  232.                 temp = SO;& l2 J1 K& Y9 |6 W
  233.         CE_High();
    7 Z2 e, P3 @% W' r2 r
  234. }; r8 d# @/ H4 k" Z% n# m

  235. $ }9 f0 P. J7 F' {1 K: o' Y  O
  236. /************************************************************************/$ n# Z8 I! i  `
  237. /* PROCEDURE: CE_High                                                                                                        */
    0 e+ l, o. e. C2 f. {
  238. /*                                                                                                                                                */  V" E8 e  A/ k2 M7 ]3 A) E) Q
  239. /* This procedure set CE = High.                                                                                */% j9 I# d. d' C4 G1 R
  240. /*                                                                                                                                                */
    9 O9 y$ j5 ?8 K2 I. |# y2 W! w
  241. /* Input:                                                                                                                                */
    - N+ M" X3 Y5 b5 M2 |
  242. /*                None                                                                                                                        */# T6 s  w$ {- r; a9 o
  243. /*                                                                                                                                                */
    - x  \7 U# L! c6 e3 t! S0 Y
  244. /* Output:                                                                                                                                */
    ! ?8 C* A  V8 w
  245. /*                CE                                                                                                                                */' y; Q  w% V8 C5 x8 A1 K5 c
  246. /*                                                                                                                                                */
    9 \( D# e) B) V- z$ _
  247. /************************************************************************/
    , z& |' i  l- F, q
  248. void CE_High()
    2 |" y% |4 E, K
  249. {, @" |' Q8 b/ A8 C; l* y
  250.         CE = 1;                                /* set CE high */
    * S' `% ?: r4 N4 A
  251. }- _4 k9 a' J0 D" C4 n

  252. - ^. Y  p  U/ H  R9 A/ l
  253. /************************************************************************/* k+ n3 h, k+ p! w
  254. /* PROCEDURE: CE_Low                                                                                                        */
    3 y$ \# _5 g, w3 U+ I
  255. /*                                                                                                                                                */
    0 P+ \0 w0 L6 s! X  L' Z8 I( x
  256. /* This procedure drives the CE of the device to low.                                          */+ z. A6 H# Z8 q) M/ _2 t
  257. /*                                                                                                                                                */
    - m  I) j/ s7 ?6 J9 t* X2 R! c' S
  258. /* Input:                                                                                                                                */) i' I$ F% E* n0 k9 t( R; P( N
  259. /*                None                                                                                                                        */+ A# ~) O7 \, ]4 ~
  260. /*                                                                                                                                                */3 g4 N1 p7 `4 D+ G
  261. /* Output:                                                                                                                                */' N8 _/ Q. j8 t
  262. /*                CE                                                                                                                                */* o) T) t, f$ s# j
  263. /*                                                                                                                                                */
    ) k+ U% g, Z9 [, O# P/ X" G
  264. /************************************************************************/
    ( L& {+ }5 U$ h# i. H
  265. void CE_Low()
    + w! N* n% {9 K  }! Z- b
  266. {       
    + F* Y" Z" U& E9 \
  267.         CE = 0;                                /* clear CE low */8 V' q: y7 Y) k8 K: j7 ^: Y( S
  268. }* @6 f, g9 M( C2 j7 o/ ~/ K

  269. : I( b$ Z+ c" N( I* Q) K/ S
  270. /************************************************************************/5 b. }/ a9 f- R2 N0 e7 o
  271. /* PROCEDURE: Hold()                                                                                                        */
    7 `) D, g5 c! l  I
  272. /*                                                                                                                                                */0 c7 _+ e* y7 x
  273. /* This procedure clears the Hold pin to low.                                                        */
    ! r: _: S  b  A  l
  274. /*                                                                                                                                                */# g  y0 N! \. d. l# b1 I
  275. /* Input:                                                                                                                                */
    . e8 Q2 y7 o+ Z- {. ^
  276. /*                None                                                                                                                        */# r* C: _# G' r
  277. /*                                                                                                                                                */' H2 l. C! w6 W- f# t( b* c0 |2 o
  278. /* Output:                                                                                                                                */
    7 r0 ^2 ^8 B( Q. b- d" {4 c, @; P
  279. /*                Hold                                                                                                                        */
      {8 n" Q% ^4 b0 o7 |
  280. /************************************************************************/
    0 d9 C- @2 L/ M; ~
  281. void Hold_Low(), }( V" h# d7 |4 H; ^! ^
  282. {% h" D0 I* z- B0 G4 L* m: @& r: [* L" q0 F
  283.         Hold = 0;                        /* clear Hold pin */; `( N) B9 a0 B; s
  284. }' |; i# T  ?( e2 f4 T- k$ A$ z) y

  285. 1 k4 ^) V  Y, ~4 Q' Q4 b
  286. /************************************************************************/
    7 y0 @( n  U9 ~  D% @; D$ b
  287. /* PROCEDURE: Unhold()                                                                                                        */
    + L) ^+ F$ i) n5 T
  288. /*                                                                                                                                                */( X3 `/ ~4 B3 B/ ]! v: Q! y
  289. /* This procedure sets the Hold pin to high.                                                        */
    % K: B: V$ o+ r. y0 z
  290. /*                                                                                                                                                */2 |" [9 N4 _9 d& o
  291. /* Input:                                                                                                                                */
    7 H6 R2 h5 o' W; S" O
  292. /*                None                                                                                                                        */
    8 |9 g. Q. _5 {0 x3 H( ?  T
  293. /*                                                                                                                                                */
    7 w! `" {( l" o: t* P
  294. /* Output:                                                                                                                                */
    7 q- Y" `' C1 R1 H! x
  295. /*                Hold                                                                                                                        */7 E. Y/ s4 J& j$ L
  296. /************************************************************************/
    4 z% N! G* l. w
  297. void Unhold()
    6 N  q3 _) D8 E: u
  298. {
    6 J6 H5 m$ ^0 _& S- y1 S0 k
  299.         Hold = 1;                        /* set Hold pin */
    + B. c- m% m) O  Y
  300. }
    3 R! o. B$ h7 {+ u( [$ a& G* E: ~
  301.   {' }7 |* L+ r2 M2 }2 H
  302. /************************************************************************/3 `, c: \/ Q* T; D9 e9 G) J
  303. /* PROCEDURE: WP()                                                                                                                */0 H) x9 F; x; i! |3 N1 X
  304. /*                                                                                                                                                */; D: S& v5 p) n
  305. /* This procedure clears the WP pin to low.                                                                */
    8 Z/ \- e+ u$ I2 |' X
  306. /*                                                                                                                                                */( s; W3 l5 f7 f0 @# O3 C
  307. /* Input:                                                                                                                                */
    + t% A# }5 D$ A  f  ~- w1 G
  308. /*                None                                                                                                                        */& _8 P- {8 \" V
  309. /*                                                                                                                                                */
    & C9 W1 m4 @' N/ g
  310. /* Output:                                                                                                                                */
    ) @( u; o, G, v- U8 j- A7 e
  311. /*                WP                                                                                                                                */
    ! U; L* J, R/ R. m* g: n
  312. /************************************************************************/
    9 k! R8 y8 N7 _  k$ U' n$ G
  313. void WP_Low(): l# a  A" V" d3 Z, l' q7 K% E
  314. {
    8 D" S7 W3 P& @' M6 ?* j
  315.         WP = 0;                                /* clear WP pin */
    * v4 @9 W8 l" C1 `6 q3 ^- I6 s2 M, x1 J
  316. }
    3 s/ ^8 e- C6 ?% u
  317. + X$ h; j& E0 N# F/ P9 E, W
  318. /************************************************************************/
    0 `6 {( x7 w; l: K8 V6 J* m
  319. /* PROCEDURE: UnWP()                                                                                                        */: v, S+ {* C$ j1 n5 s
  320. /*                                                                                                                                                */$ n' d( E6 Q3 w( K' o  p- _
  321. /* This procedure sets the WP pin to high.                                                                */3 e0 a# X( c$ ]8 R# a, }0 Q
  322. /*                                                                                                                                                */
    , T$ K) L5 n, ^% {) f8 v
  323. /* Input:                                                                                                                                */
    & V+ a, V3 \6 m  A' C% S& F* W1 S8 O
  324. /*                None                                                                                                                        */2 a: o8 H" |5 u: J1 f
  325. /*                                                                                                                                                */
    6 X5 S+ b6 i- {1 t8 I3 y* a
  326. /* Output:                                                                                                                                */9 ?/ A4 [6 q# f
  327. /*                WP                                                                                                                                */
    $ _+ d2 n" x4 Q
  328. /************************************************************************/3 D- B6 P, {/ d4 [$ m. Z( ^
  329. void UnWP()7 O* x9 a/ Z+ C" E  d. z
  330. {
    ; B9 [+ M2 B+ P( C; M3 n* C! S
  331.         WP = 1;                                /* set WP pin */
    : K$ \1 v" E8 B' v1 y/ i' L
  332. }
    + `" d: T1 \/ N- |7 U
  333. 6 f, f6 z2 C, i3 F# B
  334. /************************************************************************/' J6 B( q4 I. I7 L9 |
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    + ~  c" Z6 Z( N/ H/ `- X3 y! h
  336. /*                                                                                                                                                */
    ) E! _6 b  {- @' D  @) U' j
  337. /* This procedure read the status register and returns the byte.                */
    & u2 K. [( q% M; Y8 U) N
  338. /*                                                                                                                                                */
    & O! W& V  t$ B4 Y! @
  339. /* Input:                                                                                                                                */* z( t' \3 S& j
  340. /*                None                                                                                                                        */
    ! k7 h% R7 o$ a8 z. ]0 `
  341. /*                                                                                                                                                */
    8 z( @9 l$ Y2 f- y6 i7 {% C
  342. /* Returns:                                                                                                                                */
    5 Z( `% x* v: `; @7 T- q+ c/ x
  343. /*                byte                                                                                                                        */
    : D# X0 W1 u  i3 b
  344. /************************************************************************/
    5 W0 I/ f( N& q) V! ?( H1 z+ ^: P( w
  345. unsigned char Read_Status_Register()# r+ n  Q2 d% K( z) n$ w
  346. {% d# A( [9 z* Y5 c3 K6 _  f5 C/ H: Y1 c0 }  B
  347.         unsigned char byte = 0;
    - K- C4 l' z! Q; j2 ^; w& ~2 s
  348.         CE_Low();                                /* enable device */3 u& `7 ]! t5 K3 Q
  349.         Send_Byte(0x05);                /* send RDSR command */" E% @. s# A- L
  350.         byte = Get_Byte();                /* receive byte */
    : l2 E7 o1 {7 E
  351.         CE_High();                                /* disable device */3 E( C! n9 W* m* M) ?
  352.         return byte;
    7 {, ]3 v8 Q7 ^( D. n$ F
  353. }
    : F9 Y/ e( ^0 F9 N& |. [

  354. - k8 l  K& Z& }0 P" [! t8 _: E+ G( G
  355. /************************************************************************/0 {# c4 L6 @6 t) K' \
  356. /* PROCEDURE: EWSR                                                                                                                */+ R3 h# F5 S) v) c8 B1 M5 A
  357. /*                                                                                                                                                */
    . n5 O4 A8 |8 e" r
  358. /* This procedure Enables Write Status Register.                                                  */
    . _* W/ W4 e4 A; z  }
  359. /*                                                                                                                                                */
    5 q  Y6 _) X, `% S
  360. /* Input:                                                                                                                                */
    7 u+ q. \+ k8 z6 M' E
  361. /*                None                                                                                                                        */
    + o9 m* W+ l  N( f
  362. /*                                                                                                                                                *// w4 t+ Z# Z% t1 `
  363. /* Returns:                                                                                                                                */
    1 k% G+ b# X2 ~+ \) C
  364. /*                Nothing                                                                                                                        */2 A  l; c( U+ h6 W# m
  365. /************************************************************************/
    2 |) \4 \6 U  i8 c; L
  366. void EWSR(), @+ ~% {1 `7 ]0 N+ I% B
  367. {6 L* z) y- A0 c! h9 w" F6 r
  368.         CE_Low();                                /* enable device */
    ( V& T$ M% ?9 k
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    . k% _1 {% D9 ~5 u+ Y
  370.         CE_High();                                /* disable device */4 j; C$ w9 [  @6 H$ S
  371. }# z* _9 p2 ^# H9 d1 M

  372. # V. |+ [: x0 c. V' Z6 F9 W
  373. /************************************************************************/" ]$ u$ M5 k# ?/ q
  374. /* PROCEDURE: WRSR                                                                                                                */
    , I) J2 k: }5 y! S4 p( p6 N
  375. /*                                                                                                                                                */5 }2 T" c6 L" u) e5 y8 a( W
  376. /* This procedure writes a byte to the Status Register.                                        */
    3 @1 I- D( j; b' [5 _1 t4 }
  377. /*                                                                                                                                                */
    % b. d3 F9 @9 a9 s6 i
  378. /* Input:                                                                                                                                */
    $ h% `- U0 S% A" H- V
  379. /*                byte                                                                                                                        */9 \+ b9 f& e, ~$ |& N3 W/ v" U
  380. /*                                                                                                                                                */5 Z' H/ j" }: I9 P; ]6 L: c0 G
  381. /* Returns:                                                                                                                                */
    * O+ }- d& a) \
  382. /*                Nothing                                                                                                                        */3 N+ I5 j9 _' g" p
  383. /************************************************************************/
    1 \. @  S: _+ Q
  384. void WRSR(byte)
    & K* u1 m+ R0 o0 F) p, i
  385. {, h$ E( {& @' Y0 G! w
  386.         CE_Low();                                /* enable device */6 c* K$ }6 K3 c- m) h! l
  387.         Send_Byte(0x01);                /* select write to status register */
    4 z2 c3 A3 I: h/ {
  388.         Send_Byte(byte);                /* data that will change the status of BPx * w, S% ~& v: U# |2 }# Q8 T" p  d
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    8 n! }9 r: d; K6 \
  390.         CE_High();                                /* disable the device */
    / i7 ^+ Z- O& s1 t/ e
  391. }
    9 f6 x: T, }" P4 z0 U

  392. 9 l( w. d" g; _( z: a' h
  393. /************************************************************************/3 ]; k3 b0 _  B$ F6 u3 G
  394. /* PROCEDURE: WREN                                                                                                                */
    . d  X; y+ K/ ~; I
  395. /*                                                                                                                                                */. q* w% {( |9 j) p2 {+ {8 `/ H4 K
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    ! p& [- h, R( A" T* f
  397. /* to Enables Write Status Register.                                                                        */0 o% b! j3 n! R: E, a; O/ Z6 p4 x5 X
  398. /*                                                                                                                                                */, e0 a! R8 d$ k5 h( u
  399. /* Input:                                                                                                                                */* \% s' ~% l  i- z5 a4 _" d  |
  400. /*                None                                                                                                                        */8 c( ], U5 g. F: N/ |; S& B! s9 ~
  401. /*                                                                                                                                                */& r+ n7 ?9 m* [
  402. /* Returns:                                                                                                                                */
    & N+ l6 o; z' V9 n. w0 |
  403. /*                Nothing                                                                                                                        */
    & d, C* R5 j; x+ x/ n" c+ P
  404. /************************************************************************/
    # _0 |1 e! r  p( N  o
  405. void WREN()
    , e& {6 n! E9 c; _. _1 J
  406. {
    4 s( b& S( O1 t
  407.         CE_Low();                                /* enable device */
    $ }( ~2 {* U5 j
  408.         Send_Byte(0x06);                /* send WREN command */
    * f* n3 h" R( z4 c* H
  409.         CE_High();                                /* disable device */& x4 R8 Q' _/ ?( }; q7 s8 S
  410. }
    & y( n: Y$ D5 k$ T; v) u

  411. * Z) Q1 N+ y( s' @, J8 k" F
  412. /************************************************************************/  u% _" G- h% G; k  F* r$ R
  413. /* PROCEDURE: WRDI                                                                                                                */! h- ]' ^4 A$ d5 v; @* X
  414. /*                                                                                                                                                */6 |9 A/ v6 {: V! [; C  d, G
  415. /* This procedure disables the Write Enable Latch.                                                */0 m) G9 q/ C; p- z$ Q
  416. /*                                                                                                                                                */
    - i* }+ d) Y( O
  417. /* Input:                                                                                                                                */
    / O, l/ P4 {% x3 q
  418. /*                None                                                                                                                        */
    8 U0 X5 a1 ?8 X9 f
  419. /*                                                                                                                                                */( }/ a( E# R& J* Y
  420. /* Returns:                                                                                                                                */& J+ i% x9 G2 w  p3 C6 h
  421. /*                Nothing                                                                                                                        */
    9 M3 p9 Y& d' r6 w) e0 V
  422. /************************************************************************/
    1 X- A. A7 \% E& v3 @4 o9 _
  423. void WRDI()
    ) i/ p& ^9 g' w3 R6 E
  424. {+ \0 P2 }8 i' ]% y* D7 y5 C( M% O
  425.         CE_Low();                                /* enable device */8 P5 X# t3 k* E/ k/ m, [  O' b
  426.         Send_Byte(0x04);                /* send WRDI command */
    / D7 G" N) }3 @# s* X* \8 P$ u% I
  427.         CE_High();                                /* disable device */* b, s+ C5 O0 T2 p
  428. }9 e! D9 g  a6 c' P5 C. a

  429. & [( s! M+ h- }% e+ u9 O
  430. /************************************************************************/
    " k4 x1 w9 C5 w# ~& w: t' }  A( O
  431. /* PROCEDURE: EBSY                                                                                                                */
    5 K7 W0 I& ]% V$ y3 B  `
  432. /*                                                                                                                                                */$ G6 H, c3 W6 Z6 `! Y  s
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */3 j) J: H& [) X: L/ r6 P
  434. /* programming.                                                                                                                        */
    5 c1 b3 g7 K+ A- _
  435. /*                                                                                                                                                */
    : G( ^! Y1 @* p" g
  436. /* Input:                                                                                                                                */' m" D% k. R5 ?+ \4 @/ Q
  437. /*                None                                                                                                                        */. l# J+ J" d1 ~. S" y2 k8 f( y. ]
  438. /*                                                                                                                                                */) a+ o# T' s( Q5 b) ^2 q
  439. /* Returns:                                                                                                                                */
    / `8 S; ~& M0 T2 \
  440. /*                Nothing                                                                                                                        */
    8 P; U0 o7 b7 `, ~# g. V+ q
  441. /************************************************************************/
    ' y3 I$ p  x$ {
  442. void EBSY()8 e" G2 N, o+ a9 y$ K* y) y  c
  443. {
      c( h6 Y  V2 Z# m1 J
  444.         CE_Low();                                /* enable device */
    % h# J2 U6 z+ R+ P1 p
  445.         Send_Byte(0x70);                /* send EBSY command */
    5 f6 b/ S/ `- O9 U8 y
  446.         CE_High();                                /* disable device *// M$ P$ E2 t2 {% E! v2 t
  447. }
    2 F& r$ r% R9 Q7 v: e, g

  448. ; T% l1 ?, o7 Z
  449. /************************************************************************/! y" v( l6 l  R$ |8 P5 [5 ^$ K
  450. /* PROCEDURE: DBSY                                                                                                                */9 w/ M& v* f9 ?- y& C6 G
  451. /*                                                                                                                                                */) ~5 E1 m" z5 D4 r- c4 s2 q
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    : u1 |& l) i; u5 W. Y* _9 ^
  453. /* programming.                                                                                                                        */1 M2 X; W  F! Y* G+ Q
  454. /*                                                                                                                                                */
    ' C' ~+ d& d6 ]3 S  ^1 k
  455. /* Input:                                                                                                                                */
    : i. y. F1 `7 r: y
  456. /*                None                                                                                                                        */; g& e  Q) l; E7 u# d  L/ w4 K
  457. /*                                                                                                                                                */, {& J4 Q& x9 J9 E, n1 c+ m
  458. /* Returns:                                                                                                                                */% x8 D6 k7 A" t) ?
  459. /*                Nothing                                                                                                                        */4 L  ]$ `1 a0 `9 B1 E7 q
  460. /************************************************************************/
    & n1 `1 o. b% S# A
  461. void DBSY()
    : m4 \7 G+ q/ H% X! r8 d# U
  462. {! r+ s+ `8 F! {2 a$ z
  463.         CE_Low();                                /* enable device */) O7 g" H+ y# c& V
  464.         Send_Byte(0x80);                /* send DBSY command */
    ) ^8 Y4 s# m- L& \. {
  465.         CE_High();                                /* disable device */
    ' S% t  j$ V+ Z
  466. }
    ! f! P! _6 X% q7 c1 }; F1 V" @
  467. ' n2 p4 t- K, d
  468. /************************************************************************/2 a" F5 E5 R3 Y! q, G
  469. /* PROCEDURE: Read_ID                                                                                                        */
    ; v% p; E8 B8 o% ?+ `# w( a
  470. /*                                                                                                                                                */1 S( K3 }9 ?- q% b3 k) w
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */* P8 v8 D2 I4 ?- Y2 t: L- b' b
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */8 w! H4 T, d8 [! C, E/ A: D4 B" x
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    ! r5 V6 _) [8 x2 @* a
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    6 Q- J, U& _$ E& U
  475. /* first.  Please see the product datasheet for details.  Returns ID in */) g" t4 B' n6 `  H; p( F5 H. l: y
  476. /* variable byte.                                                                                                                */* K0 @( O' u3 K
  477. /*                                                                                                                                                */8 a/ q" s: X2 ?5 @0 e& G3 q0 @
  478. /* Input:                                                                                                                                */
    & }2 r$ z+ i$ C2 n
  479. /*                ID_addr                                                                                                                        */
    6 X! g% o0 {% j+ k, u7 H
  480. /*                                                                                                                                                */! U" V: j* }9 v3 k* v, P
  481. /* Returns:                                                                                                                                */
    , N1 i8 @, Y3 H6 n- G0 u' n/ H
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */5 V0 A+ R; c( n( f& [; o3 d
  483. /*                                                                                                                                                */# z- q9 G2 f/ G% e1 ^  I
  484. /************************************************************************/& K: q0 m: p2 P
  485. unsigned char Read_ID(ID_addr)5 o; i0 k9 m) N" t6 b
  486. {
    , N! a5 D0 E1 L
  487.         unsigned char byte;5 u/ \( ?* q  P2 {* q* t
  488.         CE_Low();                                /* enable device */
    - t$ H/ M% m  j" ~
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */; ^" Y* ~& }( r8 w; N3 i+ A1 F
  490.     Send_Byte(0x00);                /* send address */2 x) D# P$ H* f5 S* w
  491.         Send_Byte(0x00);                /* send address */5 x, o& {: s1 Q& G0 O
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */
      b9 [. }& Q, d
  493.         byte = Get_Byte();                /* receive byte */5 y3 ~/ d$ e4 S
  494.         CE_High();                                /* disable device */
      Y; d. W+ ?8 D' F; [2 \( Z+ j. L
  495.         return byte;
    7 u9 x: S4 S0 n- n
  496. }
    ! O6 I) Q1 D! M6 G2 k* l4 U) K! w6 c

  497. + X& v" `3 W, A* p4 }
  498. /************************************************************************/
    ( I$ F1 \, O! R' j$ r) [0 p7 r
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */1 x1 L, L" U9 _* M
  500. /*                                                                                                                                                */( x0 Q. F% L" ]/ L5 X; K5 p0 Z2 P
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */0 d9 V" [. x- ?
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */) j) ]1 c/ S  d+ n/ b; m
  503. /* Please see the product datasheet for details.                                                  */
    ! w9 u/ H+ L! T4 A
  504. /*                                                                                                                                                */
    ) e* s+ R. V0 V( @
  505. /* Input:                                                                                                                                */, G  q# p% l! d- H- f, m
  506. /*                None                                                                                                                        */
    # t( C' p- k8 H7 f6 \) M; Q
  507. /*                                                                                                                                                */
    & r2 d3 \: W: T* d& }: y( `
  508. /* Returns:                                                                                                                                */7 c% N* u+ W* G; S3 i0 _6 @
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    4 q8 c& O+ N8 F- [
  510. /*                 and Device ID (8Eh)                                                                                        */
    4 q! P0 y4 y$ Q; W' ]
  511. /*                                                                                                                                                */5 J/ n+ q, ^9 P6 ?0 a! p
  512. /************************************************************************/& h6 C6 O1 r1 c/ X+ F0 k
  513. unsigned long Jedec_ID_Read() % t* p$ E. ~& G: u( S2 ]  d1 Q
  514. {& ]3 P+ x* o& D
  515.         unsigned long temp;
    * t1 l5 M* e' O' r
  516.        
    ; B# b% W+ y! f' r% a8 ]* V9 w3 Y" u
  517.         temp = 0;
    " O& P' s- M% {* z* v5 D2 X" W& J

  518. 2 W) ^; c3 x8 Y0 O( E& ?
  519.         CE_Low();                                        /* enable device */
    5 S5 E3 [$ J2 X3 M  M* D, c: p
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */# F6 I7 D: X. n  ?; M9 e
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */4 _* f+ I3 j: p% E$ U& y
  522.         temp = (temp | Get_Byte()) << 8;        5 H5 k+ _4 t! [0 z) o( E( ?
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */; q! V: V" u" Q  z
  524.         CE_High();                                                        /* disable device */- ~! g6 Z6 U! k# k- M7 J6 K: ~, p
  525. 6 t, C" U# t, f3 h" H6 g& H
  526.         return temp;4 K1 X& P; R/ p4 L5 y- f$ i
  527. }
    % s, R7 E) \, w) l9 ^& h7 v8 l
  528. 5 r7 o6 u) w" F' V6 o3 s
  529. /************************************************************************/
    ( G0 H) {( M/ F9 L" K2 \
  530. /* PROCEDURE:        Read                                                                                                        */
    $ V& _8 \2 l, o9 `" M
  531. /*                                                                                                                                                */               
    ; D; q& j7 E5 L( ^4 w1 J+ M0 E
  532. /* This procedure reads one address of the device.  It will return the         */7 P! l+ E9 }3 b! s; d
  533. /* byte read in variable byte.                                                                                        */9 c7 B, [, X6 P  l2 q
  534. /*                                                                                                                                                */7 W9 I& ~0 e# @6 r% j; X# H
  535. /*                                                                                                                                                */
    ) l) P% m6 ?7 |( V
  536. /*                                                                                                                                                */  A7 r4 ^; B3 \* i1 M
  537. /* Input:                                                                                                                                */! g, J7 K- ~; w& y  Y% J' ]
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */' q: \! ]) H2 q8 c& A
  539. /*                                                                                                                                      */
    : m4 ~4 |; d2 s- \# _1 U. v& w# _
  540. /*                                                                                                                                                *// G4 i# {# z9 o, E+ c, l
  541. /* Returns:                                                                                                                                */
    7 D0 q6 ^8 Z" I
  542. /*                byte                                                                                                                        */
    : s, l+ O7 g- E+ Z
  543. /*                                                                                                                                                */1 `8 v# x) ]' [1 }8 J6 X
  544. /************************************************************************/
    5 H1 p) m+ p. G
  545. unsigned char Read(unsigned long Dst)
    4 p, I0 p$ f6 L- E, n  _$ h
  546. {
    , P/ ~4 H- N6 R# O$ @) x/ E. f
  547.         unsigned char byte = 0;        + |) z* c& A# z% }6 ?. Y6 l( a

  548. 0 O2 e# u0 m: L- y( u4 F
  549.         CE_Low();                                /* enable device */
    8 G; U1 g! V, y7 a
  550.         Send_Byte(0x03);                 /* read command */9 E" r, D) a, x2 T6 T
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */4 D( }2 s* c0 e+ T2 P" ?6 U
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));1 @+ P- t+ Y5 _0 |
  553.         Send_Byte(Dst & 0xFF);# k- J+ ]  Y1 e' l4 H. Y  I! s1 e
  554.         byte = Get_Byte();
    2 s8 m- l$ C" E" V
  555.         CE_High();                                /* disable device */
    " Z! P' U: P! G
  556.         return byte;                        /* return one byte read */3 I$ w6 ?+ @' h  [; `
  557. }
    4 s7 E5 w  x* g( w5 s3 m! ^
  558. 7 R4 y( U4 X; `
  559. /************************************************************************/
    + R* w' t# A' V! u* [1 w7 g
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    * ?6 f3 y# a9 `
  561. /*                                                                                                                                                */               
    ; E/ V4 t, I1 C, _
  562. /* This procedure reads multiple addresses of the device and stores                */" k, ~; `* |; k# i* e2 B, V
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    5 f  _' z6 Q2 L3 i" W8 l% I
  564. /*                                                                                                                                                */
    + L0 G; G( r  g0 d8 y2 u- I5 d  X
  565. /* Input:                                                                                                                                */
    6 i6 g7 S" T/ q. y" ^& {
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    5 P/ q" M; ]0 l  a# z
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    ; `4 z/ {. V+ N7 t0 P2 p
  568. /*                                                                                                                                                */
    % D, B2 D* Z& @6 A1 I8 e2 x
  569. /* Returns:                                                                                                                                */
    ) u' k! i: s, K7 i
  570. /*                Nothing                                                                                                                        */
    9 t0 u2 Z9 R6 s* z) l. b+ ?" q
  571. /*                                                                                                                                                */
    # J2 H! Q) g4 D; y0 [# {8 C' f
  572. /************************************************************************/
    9 b9 a; q. Y3 z0 A* p( I) P2 v6 }
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)4 G% ^6 U1 Y+ v3 B5 F# k( d
  574. {# A0 Z; J/ u* k) k' N! K5 d4 g
  575.         unsigned long i = 0;+ r/ b/ D+ t* R/ j
  576.         CE_Low();                                        /* enable device */4 v3 B- Q( F# E
  577.         Send_Byte(0x03);                         /* read command */
    5 A% ?* i: ^/ j* k& V" s; x% G
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ( a# |6 Q9 I& p$ }
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    7 R5 c' `' r/ V) t
  580.         Send_Byte(Dst & 0xFF);" u, C0 n3 I. i% t
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    " P- K6 }! C$ Y' _- _
  582.         {) w7 o; t& O: w$ ~! N. c
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    # C, h  t$ `1 U
  584.         }
    ) Z3 f: Y9 R, y* K% u- b1 o5 G
  585.         CE_High();                                        /* disable device */3 e; J! W8 ^0 m3 _

  586. " l; S- n( k8 J& R
  587. }$ x6 q) h, h6 x& @, f, E; u

  588. 4 m- L! R3 o: K2 A& C5 d
  589. /************************************************************************/
    ; \4 {, P& `, ?7 C( z4 U8 Z
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */9 w6 m; b6 q  v
  591. /*                                                                                                                                                */                5 E& b6 m9 y& i, v
  592. /* This procedure reads one address of the device.  It will return the         */
    ; E" m5 @: v: |! M- {( m. g
  593. /* byte read in variable byte.                                                                                        */
    : f# L7 r' D1 Z+ b, i9 G. n
  594. /*                                                                                                                                                */
    ' ]9 p% z- F( B4 O9 p* h& Y' v
  595. /*                                                                                                                                                */
    6 @( ?2 v" H0 R4 }( }3 w! B* c) r! Z3 H
  596. /*                                                                                                                                                */( L# z' N, X( l6 H; m' w
  597. /* Input:                                                                                                                                */
    2 ^" Z9 i2 O" _
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    - y& T! X5 U! @5 v# _  M
  599. /*                                                                                                                                      */. b- p' {" A: W
  600. /*                                                                                                                                                */* d* Q9 F7 s. u6 a
  601. /* Returns:                                                                                                                                */6 V5 e! S+ H, \* f
  602. /*                byte                                                                                                                        */
    ! B( y7 D9 E3 k# v9 L) p: O
  603. /*                                                                                                                                                */
    & h# e. d8 ^% i: J9 G
  604. /************************************************************************/
    % ?6 _! ?% m* S) D, Z7 J
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    / ]3 Y! F0 H" F; t, N3 T
  606. {- }4 w( _0 V4 _* x. z  l( V3 G
  607.         unsigned char byte = 0;        0 P1 ]" H1 y$ m$ X% K! G
  608. ! L; _4 Q+ N1 s; W% c
  609.         CE_Low();                                /* enable device */0 p* W& L' p1 J' h
  610.         Send_Byte(0x0B);                 /* read command */. j+ Y' L: @, o" J% Y$ k
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    # d3 ^9 R& h6 a* a) g& N
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));. ?: L, B! L2 }; N
  613.         Send_Byte(Dst & 0xFF);
    6 N. t2 O) i2 Z; O* M6 R
  614.         Send_Byte(0xFF);                /*dummy byte*/* w4 E! M) i8 Y
  615.         byte = Get_Byte();
    ( m& E+ e# d4 f& t/ ?
  616.         CE_High();                                /* disable device */
    8 k5 G+ I' ^* x& O/ d$ q4 {
  617.         return byte;                        /* return one byte read */( s' _* G6 j3 p  W  V* U7 K0 S
  618. }
    % y* o1 Q6 r2 j) F, U% B& K

  619. + o% u" F* t5 j/ ?; e, U4 N3 K
  620. /************************************************************************/4 Q4 K* O0 h5 `/ W) h! X" j, y' C
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */) P6 w4 `2 G. `  [
  622. /*                                                                                                                                                */               
    9 O" J0 u! O8 w. X8 p* D, ?* U: T
  623. /* This procedure reads multiple addresses of the device and stores                */- G+ L; d- f0 d1 W' }" w
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*// d+ {* N: x& }* I
  625. /*                                                                                                                                                */$ }# q5 ~% ~6 }3 P# n/ j
  626. /* Input:                                                                                                                                */
    ( o0 [5 Z: ^! Y8 @& j8 L8 H8 @! Z! U) N
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */6 r3 ~" O! i) v6 i
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    6 r- W+ q, \5 k
  629. /*                                                                                                                                                */6 |* ]8 u- I  a; m
  630. /* Returns:                                                                                                                                */
    . a! b" K6 I% b$ J
  631. /*                Nothing                                                                                                                        */
      ?0 J# e+ \6 a4 t$ W
  632. /*                                                                                                                                                */  w5 c7 K% M! ]- d1 n
  633. /************************************************************************/1 A' O8 E( L% p+ u' g. d: M
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    ' y# f# D% y! L( e) l& X0 D, Q
  635. {9 v7 n1 H+ W# V. [3 }
  636.         unsigned long i = 0;
    + ]: z5 i4 f( ^8 p& k
  637.         CE_Low();                                        /* enable device */
    ( x: ?6 d) t8 u8 d9 [' n8 {
  638.         Send_Byte(0x0B);                         /* read command */. h' ?$ F7 K9 O0 C' _* [4 c! Z
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */4 P& |0 K& t1 j! u7 y4 d
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    " o( ?) o. E1 \- W
  641.         Send_Byte(Dst & 0xFF);
    " o! v; p( [. D; e- g' e. q) z1 L
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    ; _" o, ?, q8 q' j+ h
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */8 F( s! l5 k( Y: f" ~* O8 ?
  644.         {
    ; R9 i4 |% s2 k
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */1 a- D- U8 e+ _% y
  646.         }4 U% ^; P4 u+ }7 z
  647.         CE_High();                                /* disable device */$ e1 N7 Y2 G) r! D! G4 F
  648. }
    ! d3 p5 C% {4 `! Z, J. C
  649. 9 O2 |: s  K7 g$ b& y' S
  650. /************************************************************************/% ^0 }( J* f+ ]0 u4 c
  651. /* PROCEDURE:        Byte_Program                                                                                        */
    1 x' R+ Q/ w9 T: q
  652. /*                                                                                                                                                */
    2 b: X* S: b( t' a
  653. /* This procedure programs one address of the device.                                        */% s9 H; y! v7 v2 }2 L$ \% M1 \
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    0 b2 H7 d6 C2 g. z/ `
  655. /* block protected.                                                                                                                */
    % z+ t/ v% @: Z; T, ?- U, s
  656. /*                                                                                                                                                */
    9 f5 [. G* ^9 A8 B/ F% i
  657. /*                                                                                                                                                */6 K2 f( G' @) j* x( p/ k: _" I
  658. /*                                                                                                                                                */$ x& r1 ~: L& X1 D0 Q
  659. /* Input:                                                                                                                                */& Y% d' S+ K) f2 W
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                *// B. s* Y1 K( {" j% u
  661. /*                byte:                byte to be programmed                                                                */7 f% O3 w4 k2 r0 ^/ t1 L9 e
  662. /*                                                                                                                                      */
    : `7 T# c: j2 y" r
  663. /*                                                                                                                                                */
    ; m5 n/ `: _7 T  {- @7 q
  664. /* Returns:                                                                                                                                *// l0 C: d# J* `6 z# ?
  665. /*                Nothing                                                                                                                        */- H' s1 c* n- q4 t
  666. /*                                                                                                                                                */
    $ q) E4 {- @/ O
  667. /************************************************************************/* k- b$ X: y% n- q
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    6 g+ v* F2 q$ Q3 L
  669. {
    ! r. t# x- o6 t/ u2 h( e' ]
  670.         CE_Low();                                        /* enable device */6 D1 S' m: \! E4 a! d4 K
  671.         Send_Byte(0x02);                         /* send Byte Program command */! x) \" P- m) N
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */) t/ W/ w3 Z; Y. G
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));2 U7 V( }3 g8 n
  674.         Send_Byte(Dst & 0xFF);2 T% G: t2 G- a( h
  675.         Send_Byte(byte);                        /* send byte to be programmed */2 O+ b% j4 Y/ L2 I) I6 I/ Z5 U( O$ ?0 q
  676.         CE_High();                                        /* disable device */
    ( D, C- p. u0 a! a$ p1 d8 \6 |
  677. }% T4 E% H, A8 j+ i" Z' \- B
  678. 2 G! y; C; j6 k! U! P- C" l) Q
  679. /************************************************************************/3 O" U# K$ m5 F) P3 m, y1 a! H  z/ B
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */( Z! j, u  ~% k2 Y, O- C+ N! U
  681. /*                                                                                                                                                */
    , n7 f' L- L( P! N3 J  E8 M/ c" L( N
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/
    : y( `' R, C+ P+ F
  683. /* the device:  1st data byte will be programmed into the initial                 */' u* _, t5 v3 m3 v4 B
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    ) k( v7 [, S5 R! [  i
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */$ u. z! z5 L8 N, ~- S7 ?0 a- M/ k
  686. /* is used to to start the AAI process.  It should be followed by                 */: h$ b6 Z1 }% k, S$ R% E* N! D
  687. /* Auto_Add_IncB.                                                                                                                */
    : q* g9 e3 I7 L- n, ~8 y* V; H6 K
  688. /* Assumption:  Address being programmed is already erased and is NOT        */2 c% V, G. Q* o
  689. /*                                block protected.                                                                                */
    ! q, \( ^4 |3 g9 y/ u8 X$ q. g
  690. /*                                                                                                                                                */
    * `/ X5 X8 |' u- f: ^! z6 w$ v/ t, w
  691. /*                                                                                                                                                */
    5 h2 }1 E) @4 Q* P+ k% B1 @
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    4 s  W. \, {' X2 w7 g" u7 K9 O
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    ( x$ ~$ k- a) \; p% M0 {
  694. /*         unless AAI is programming the last address or last address of                */3 V% K" ~/ e: V% z
  695. /*          unprotected block, which automatically exits AAI mode.                                */
    1 c& V) R$ {0 G2 P- l( k# K5 s
  696. /*                                                                                                                                                */
    & R# C( `" i0 e! d: R
  697. /* Input:                                                                                                                                */
    2 w2 R) h% i9 o9 W. F
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */5 g' C( N6 C- g% v( ^$ v
  699. /*                byte1:                1st byte to be programmed                                                        */
    $ F+ G7 {, r0 o) _% k, P/ M$ F
  700. /*      byte1:                2nd byte to be programmed                                                        */
    ! j/ T4 c1 q* d" t
  701. /*                                                                                                                                                */
    * V# k) M/ y+ K7 }
  702. /* Returns:                                                                                                                                */! B$ }& Z" p2 n: x
  703. /*                Nothing                                                                                                                        */
    - b) f: r- m6 P* I! ~
  704. /*                                                                                                                                                */
    # s( V) O! l4 }% a' M
  705. /************************************************************************/
    9 h/ P; I+ I( Y3 r! F
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)$ e! z. }4 Y. j1 {7 `/ H$ w
  707. {/ u) ?! h( ?4 x1 {9 g! _5 t$ B' S
  708.         CE_Low();                                        /* enable device */
    * `4 n+ S" t9 x' z) q- j6 z
  709.         Send_Byte(0xAD);                        /* send AAI command */
    ! T7 y6 E0 Y7 Q! a# M; @/ i3 P
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    - [+ f; W  j6 r! Y! L8 L; y
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));1 P7 I+ c1 B5 W9 s
  712.         Send_Byte(Dst & 0xFF);8 r% f# l$ ~$ F5 m9 T
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        . S# p. B; p3 b( e
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */; h  k  K* w2 K6 [1 x) g5 q, d
  715.         CE_High();                                        /* disable device */2 K$ i: l/ w. d/ k* {
  716. }4 ^. }9 W" f8 c& R3 G
  717. 0 O+ R) N- j2 o4 l/ d% d9 N
  718. /************************************************************************/5 L/ z$ J5 n* |  G( r+ R
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */- x- \& i8 z* q1 P. v: Y) b! s" U) H
  720. /*                                                                                                                                                */
    0 Y2 j/ n6 E- z+ c" `' y
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/, `+ C/ W( U8 |9 r) i# D) W' y5 U
  722. /* the device:  1st data byte will be programmed into the initial                 */8 T+ U2 B! U9 F4 E% s
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    4 `7 n1 y$ P1 ^# _
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    7 f3 v6 `3 b$ A* A0 [$ ]0 `8 q
  725. /* is used after Auto_Address_IncA.                                                                                */+ g: y9 n5 f1 n* X. M* ?
  726. /* Assumption:  Address being programmed is already erased and is NOT        */! S8 d) w7 p( y
  727. /*                                block protected.                                                                                */
    4 d& C+ P2 J# M3 ]# I8 b* t
  728. /*                                                                                                                                                */+ N+ g9 R+ J4 t' w, E  n9 g
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    " o9 o7 ~: z" F8 |
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */: b0 L4 ?6 T$ G4 L
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */$ ?% _; j& ]! H$ t
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    ' M6 q6 q( L3 n8 G
  733. /*         last address of unprotected block, which automatically exits                 */+ |/ o" J9 z' J, L, A
  734. /*         AAI mode.                                                                                                                        */0 Z1 Y; v: _4 p8 M, s+ O  O/ O
  735. /*                                                                                                                                                */
    & {5 f' N5 l, l  [& y5 d  o
  736. /* Input:                                                                                                                                */
    * {/ t; C! n# W/ r0 w. C
  737. /*                                                                                                                                                */  X& C) Z" k( u2 [1 E! _$ H8 `, k
  738. /*                byte1:                1st byte to be programmed                                                        */
    - h, D  }9 Q' h: c* e
  739. /*                byte2:                2nd byte to be programmed                                                        */
    $ o3 G. g% g4 H7 t  ]/ F+ Y
  740. /*                                                                                                                                      */
    ) }7 c: ]1 V7 \' m7 r
  741. /*                                                                                                                                                */4 L3 Z8 L  c5 X# p9 P' Y) @" [6 G
  742. /* Returns:                                                                                                                                */1 I( d" g2 Z# L5 X2 o* y
  743. /*                Nothing                                                                                                                        */0 y( P$ E+ v. M
  744. /*                                                                                                                                                */
    + f; g  G) ^6 d
  745. /************************************************************************/
    + g9 z% L# h4 e1 [; W' o
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    : m/ u0 p; w# G8 S6 E
  747. {
    4 n$ t. n9 I. _4 w9 s' J
  748.         CE_Low();                                        /* enable device */
    1 S( k" y$ b" a3 v4 N  u
  749.         Send_Byte(0xAD);                        /* send AAI command */7 O& x( o: s- r9 x) F* t
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */
    4 ?7 K  i. U0 U+ G& Q, x1 P4 O$ V
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */; y2 v3 ^0 S$ }
  752.         CE_High();                                        /* disable device */& C; s/ y& x8 }/ r+ S' u9 R) l1 t
  753. }
    & c/ t+ T, g, m

  754. ; B  ?& L+ J$ u' u( d9 @/ J
  755. /************************************************************************/
    # n8 A) R, [. y
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */! R1 C8 f. T. G6 {$ y  K$ F
  757. /*                                                                                                                                                */: [) z/ G: l) r1 `( Y( _
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    # x; x0 Z$ Y" g. h+ a, O
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */2 s4 t7 s; f9 y, O
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    ) \) w( J* w# U
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    ( B" }* i0 l! B% p* _
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */0 A6 n4 @7 d0 O8 o" h* j
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */9 ^' Y5 ~+ f+ I3 F
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */; q( x$ S3 d( M9 `# d
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    ; C7 s% s/ y3 J. F9 q* w8 u, h  I$ O
  766. /*                                block protected.                                                                                */- o# w# T& _- g# \4 p
  767. /*                                                                                                                                                */1 Y% r* y5 M; @
  768. /*                                                                                                                                                */
    ( r& e. J' Q! C9 F- \. F' |
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    , K- D* Q: {- \6 C  v6 k7 [
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */( ]# p" t9 }% C1 B& X0 Q
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */( H1 D' n( y8 j6 r7 K7 Z
  772. /*          to exit AAI mode unless AAI is programming the last address or                */* k9 s3 Z2 X" c" N0 D: J
  773. /*         last address of unprotected block, which automatically exits                 */
    $ u7 l  {) c! I! a1 N! M; ?9 z( j2 f
  774. /*         AAI mode.                                                                                                                        */
    5 g2 C  z3 e7 E
  775. /*                                                                                                                                                */1 W' U" \5 w2 j
  776. /* Input:                                                                                                                                */1 i4 K# t9 U  r' A: a
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
      e' V9 u) a) v7 `$ t+ T% r1 J0 ^% A
  778. /*                byte1:                1st byte to be programmed                                                        */
    : F9 a, r/ U. }$ h
  779. /*      byte1:                2nd byte to be programmed                                                        */
    * B, Y( x' N1 f" L) o- F
  780. /*                                                                                                                                                */; i7 i( L# y! R
  781. /* Returns:                                                                                                                                */7 p& t, h' a  x0 D. H
  782. /*                Nothing                                                                                                                        */- F4 ?5 A" g, m& _1 X$ d
  783. /*                                                                                                                                                */
    & i$ @7 i* b3 h% J$ m% J/ a
  784. /************************************************************************/
    0 h! a+ C, v) a" O
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    5 D9 p1 V: b3 z
  786. {8 N! e. u- W, S3 K
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        # J1 e+ Z9 g  h) Q' m4 k+ u  m  b
  788. " B5 d; b" \% F: k
  789.         CE_Low();                                        /* enable device */
    3 z4 n( w0 ]- _! t6 a2 [$ @1 o  B% d
  790.         Send_Byte(0xAD);                        /* send AAI command */3 I* q$ S% H, N- G9 M
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */7 h$ A: V% E: E# i+ ?/ T
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
      J* A; b7 w; `# B
  793.         Send_Byte(Dst & 0xFF);7 o8 T, ^9 D' Y. F- n0 B, s3 P6 D
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    " c) J2 j3 I6 c0 A# L% q
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    * d) Z- T3 C" v* b7 _
  796.         CE_High();                                        /* disable device */
    / H% U$ E3 [/ f6 f& n
  797.        
    3 \% Q/ S3 M! i" m4 P
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */0 h/ D2 z  m( |) b& N) S5 `, g
  799. ( E0 x. Y0 A% L, I; E: X1 I
  800. }8 \! ^. G' p1 {/ ^" k' o
  801. 6 j  w/ t1 s" P/ U! d, F
  802. /************************************************************************/5 d! p; @' g) a
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */6 ?, ]# r$ n6 Q6 V) F; J( ~; X
  804. /*                                                                                                                                                */
    2 ~1 X! q5 K) [+ a$ A+ O- j
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    : g7 \( \3 F) n# r/ {
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */; f7 S7 \" ~# V$ N8 S5 `
  807. /* AAI programmming is completed.  It programs consecutive addresses of */( m3 l3 ?- \! o6 B
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    + ?7 {( b4 M3 ~# a# f  ~
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */
    , k, T. A3 E1 `9 ~$ w1 s
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    + \7 h3 @3 [) C5 |9 Y# n
  811. /* used after Auto_Address_IncA.                                                                                */6 h3 T, F6 p: F+ M* x3 Z8 `! E
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    5 M, L# T/ G- \  X! k
  813. /*                                block protected.                                                                                */
    ) J/ ]# q8 H% S8 ]) ]8 A, T
  814. /*                                                                                                                                                */; V4 y; O8 x. c' y  {& O2 W
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ) \% {! A) c1 L8 C- `  k/ l) C& j
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    0 ~% E* Q7 ?1 t" @) c  l% B- a
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    9 h" D  r& t  [" p) y2 }: ~
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    % s8 i) w% n. J9 s* N
  819. /*         last address of unprotected block, which automatically exits                 */
    8 ], o5 V; c8 s
  820. /*         AAI mode.                                                                                                                        */% u+ B  Y; X2 t/ l6 M+ Y' f
  821. /*                                                                                                                                                */& m7 G6 y0 [: U
  822. /* Input:                                                                                                                                */2 \" g- ~' k" N5 R( o2 R8 {
  823. /*                                                                                                                                                */% K$ }2 a! T8 B1 J. N
  824. /*                byte1:                1st byte to be programmed                                                        */
    + l1 L0 q  U/ D8 J" X( W" X0 M
  825. /*                byte2:                2nd byte to be programmed                                                        */$ I' @' z4 S/ A4 u
  826. /*                                                                                                                                      */
    5 C& C8 f' G9 @: C& C
  827. /*                                                                                                                                                */
      i3 t7 E/ n" [7 K) v- c8 o( ]* h
  828. /* Returns:                                                                                                                                */; z. ]' Q, \4 U) g
  829. /*                Nothing                                                                                                                        */
    ( r" [5 |5 c( C5 b+ j/ q$ U
  830. /*                                                                                                                                                */9 [( B+ V% N; H! V
  831. /************************************************************************/9 {% _* |2 l' X# P( G
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
    3 S( U/ f+ t2 C' ^
  833. {3 q+ v3 f& _/ ?) s# P( u
  834.         CE_Low();                                /* enable device */! _- R, ]0 s" G# `! R; `, u
  835.         Send_Byte(0xAD);                /* send AAI command */
    ' V4 k/ G4 ^# B
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    1 N  B5 I+ i9 `8 u+ R/ `! I
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */$ _  l/ g# O) I
  838.         CE_High();                                /* disable device */+ v8 X2 `5 Q* u% l

  839. + s. c* {) O+ r) m) N+ r% k7 O
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    6 z% ?) a* O5 `) ~+ z! ?& ~
  841. 1 Y# f' T! R5 G) |6 n/ {7 ]0 M
  842.         WRDI();                                 /* Exit AAI before executing DBSY */5 ~8 {5 r* ~- X1 ]* O
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    7 k7 Z  |: l6 Y
  844. }
    2 l3 `! Q& c/ E; i1 l, ?* {% _

  845. 3 I8 |, N* n1 e7 y$ ^
  846. /************************************************************************/
    1 W$ @# A1 q7 [7 @7 \
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    ( K; w& [7 m: \4 {1 \6 {
  848. /*                                                                                                                                                */
    $ q! T( X/ e( P' ]( c& j
  849. /* This procedure erases the entire Chip.                                                                */" f+ |$ b! K, j4 Z+ ]
  850. /*                                                                                                                                                */
    ! _5 T+ N7 e  w2 o
  851. /* Input:                                                                                                                                */
    + I$ U* U% @; e& l( Y
  852. /*                None                                                                                                                        */6 d  p: e- d5 h$ Z
  853. /*                                                                                                                                                */, q# G% D. m. H+ J- b
  854. /* Returns:                                                                                                                                */& W1 C. L" ^6 O; B3 O" \  U  }" v! H
  855. /*                Nothing                                                                                                                        */) ^; Y. b1 G4 z' u' t
  856. /************************************************************************/
    9 e) f2 {9 x. C
  857. void Chip_Erase(), v5 `9 m* ?1 S8 }, s/ H# o4 w
  858. {                                                ' t. |9 ^9 B& n
  859.         CE_Low();                                /* enable device */- o+ `3 D+ A. y% z9 e( ]  ]0 e) R
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */& E3 ~' X# m; \5 M; B
  861.         CE_High();                                /* disable device */5 l* e7 i" [/ T; l2 O
  862. }4 R! ]$ _1 E9 H1 p: L
  863. 3 t4 d; ^, K+ w
  864. /************************************************************************/) q9 i, g- l! A) n; ]
  865. /* PROCEDURE: Sector_Erase                                                                                                */
    ( g, M; g( P  b3 C. I6 S# ~1 f6 r
  866. /*                                                                                                                                                */9 u7 g# `- Q: Q
  867. /* This procedure Sector Erases the Chip.                                                                */
    " h* Q8 E# d* f8 j
  868. /*                                                                                                                                                */( K9 O2 K$ L/ n" Q9 m* n5 E
  869. /* Input:                                                                                                                                */
    2 n. }, p% @9 Y7 ?. _- E  Z
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ) U3 w* `2 z& M- t% b0 a, j& d1 I4 t5 l
  871. /*                                                                                                                                                */- @3 `9 C9 r1 P, b5 {4 E
  872. /* Returns:                                                                                                                                */
    % Y  H2 m, s1 K9 v* X+ d# R
  873. /*                Nothing                                                                                                                        */1 W4 K" Y; K+ F3 r4 B
  874. /************************************************************************/$ M! F8 t9 u7 q
  875. void Sector_Erase(unsigned long Dst)1 S( H$ Z+ t5 f; p2 P
  876. {
    ) D& r: {9 G. f7 T
  877. + O" G% f6 \" r/ \+ z3 D7 S  e

  878. " @  u  C* \# O! ?+ T: v" T
  879.         CE_Low();                                        /* enable device *// X0 `- C+ p( n. B$ z1 Q
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    * z6 j+ o- X; X% ^- {
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */7 s( i! L$ F+ N7 A
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    / c4 F$ ^3 l+ d3 f6 q0 A7 r4 d0 f
  883.         Send_Byte(Dst & 0xFF);" v( ~0 v1 Y; |
  884.         CE_High();                                        /* disable device */
    5 b* }& y$ i& z& O
  885. }        2 D' D/ n+ b4 ~  X
  886. ; @- V% O/ Y- a0 A+ D# x7 O
  887. /************************************************************************/. H) Y8 N+ h. k* l8 S
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    5 G. G& Q) q8 `! h1 l7 W/ w$ X* y
  889. /*                                                                                                                                                */7 }& a# l+ }; J8 L' s6 ^0 f
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */' M7 N/ }* f: h* h: e
  891. /*                                                                                                                                                */2 p( E5 T* W6 ~9 h& b  T7 L
  892. /* Input:                                                                                                                                */" P5 S5 @6 [; f6 e4 d
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */: ^, U' T2 Y4 p9 o; J
  894. /*                                                                                                                                                */  \  M) g* g* c; \" _; {
  895. /* Returns:                                                                                                                                */% u/ q9 S0 r4 g2 a1 ^
  896. /*                Nothing                                                                                                                        */
    9 F1 P5 o% p# h( S1 G+ g6 H
  897. /************************************************************************/
    4 `; i7 W  |5 |
  898. void Block_Erase_32K(unsigned long Dst)
    2 L* g  B/ [/ g7 O. k' J
  899. {
    & q3 R/ ?- K$ J$ I$ _" U7 T* i8 C
  900.         CE_Low();                                        /* enable device */
    ) Z/ H+ j4 S& X' |& i
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */; B( ^) E6 u# B  n
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */0 X7 P+ B  j9 o1 @! k4 S+ F
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    4 e$ b, R9 ]& h" R% p
  904.         Send_Byte(Dst & 0xFF);
    3 l- `  G+ X- G( e
  905.         CE_High();                                        /* disable device */( F8 M, c0 j  P! n
  906. }
    . M' W5 Q" w2 n( Q$ i) t
  907. / o" Q# S/ t$ g0 n1 q
  908. /************************************************************************/
    " m' p0 z2 T7 Q, Y$ L! ~: G; D$ @
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */* P- e/ h' p& z0 W! r' L  [
  910. /*                                                                                                                                                */+ S: C6 ?! m) B8 I3 \, M$ y/ }
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    1 ]: C! \- o: h
  912. /*                                                                                                                                                */
    5 K8 X( \! {$ n  Y  H
  913. /* Input:                                                                                                                                */
    & T* [- v; K# e7 f
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    $ j# T3 O+ a+ i- [& I
  915. /*                                                                                                                                                */
    ( L! r! H, }/ O: g% P
  916. /* Returns:                                                                                                                                */8 p+ A* L/ ?) W! M: P1 v
  917. /*                Nothing                                                                                                                        */
    5 f3 h4 [  f3 J9 C. _2 m
  918. /************************************************************************/
    1 D9 _+ P+ j7 T( }6 C
  919. void Block_Erase_64K(unsigned long Dst)
    4 R3 v& ~9 r, s8 V
  920. {
    & p. z9 _& u6 c5 Z: A/ N2 o
  921.         CE_Low();                                        /* enable device */
    2 X/ E9 d( p# d. |3 y
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    1 P5 v' C; ^1 F/ I1 Z; s2 _1 L: y, M
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */. k2 Z1 d& |+ m- W6 f
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - f) H, b. E. |4 \6 g. d2 x) m
  925.         Send_Byte(Dst & 0xFF);: e6 [# o( Y% l$ A
  926.         CE_High();                                        /* disable device */; V/ l1 ?8 G4 M: Q5 k
  927. }; n3 \8 T& Y4 G) i4 `" [# @' u! d

  928. 4 w* Y9 t- o3 v, s& H
  929. /************************************************************************/
    , ?+ b. ]) `5 K, o
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    - x" ^. P0 f  A, ?  ]7 V' m, L
  931. /*                                                                                                                                                */
    ' B, x- `; K( Z6 [. v) i4 v3 J
  932. /* This procedure waits until device is no longer busy (can be used by        */
      `8 \, P, X3 f
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    " S; E/ D' [$ v; G* G6 A) ]
  934. /*                                                                                                                                                */
    9 a: O( L5 U5 k. k' S% x1 C
  935. /* Input:                                                                                                                                */! F) }. g. U) P5 x1 L6 `, l( Y" o
  936. /*                None                                                                                                                        */
    ; b( I7 ^) i- D4 G+ {
  937. /*                                                                                                                                                */: P( u; Q' n5 X- ~" J9 ]/ Q
  938. /* Returns:                                                                                                                                */& h; r2 U/ @' ?+ p3 D0 `& G
  939. /*                Nothing                                                                                                                        */
    " @7 [4 F) }0 y( a8 Y
  940. /************************************************************************/
    # y& p1 Q9 [6 L( ~0 J' Q
  941. void Wait_Busy()
    ) F/ G5 h, S, O, ?% j4 R5 x( k) O
  942. {$ j& R& B8 i/ b3 M" w
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */6 F% B- L/ ?  I4 E: R/ m. P
  944.                 Read_Status_Register();
    $ Q- E. ^# k$ C5 o
  945. }
    ) M6 e3 h: ^: A6 k0 h$ G, G& P

  946. 6 x: ~% E* y: c* H/ F, l% H
  947. /************************************************************************/
    1 t7 ~5 j0 O0 D* }
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    9 w$ }* T% L* o. o4 a. |
  949. /*                                                                                                                                                */
    ' |' U  H. |$ c- ]0 K# p
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
      k, o3 c& ?2 B& D
  951. /*                                                                                                                                                */
    " h9 y- y) s. Z" V- J
  952. /* Input:                                                                                                                                */
    4 Z& w- g. e) }; p
  953. /*                None                                                                                                                        */
    8 i$ l) ?: {  G4 ~+ `
  954. /*                                                                                                                                                */& w2 a  V9 s" y: W0 Y" n2 ^
  955. /* Returns:                                                                                                                                */
    ( u+ K) G4 P1 a' ^" ?6 p
  956. /*                Nothing                                                                                                                        */
    ( J. V2 k$ |5 Q, `, U
  957. /************************************************************************/
    ' T! [/ q; ^0 [% o9 }$ r
  958. void Wait_Busy_AAI()) \7 C% t. t6 i, K3 h9 Y. s- G
  959. {
    : T  I  r: ?1 _/ w$ |8 t' N) M
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    ( C; W  t. {) P0 c+ ]' _* }; I8 _
  961.                 Read_Status_Register();" |8 r4 U) s4 M* n
  962. }1 r3 f% w" O9 b5 P) c$ ^

  963. # ~9 P, N! o: z* q1 q
  964. /************************************************************************/; R; m7 J, O8 u, q# h6 ~  `6 Y
  965. /* PROCEDURE: WREN_Check                                                                                                */  t/ x3 h. p  v% z+ m( J
  966. /*                                                                                                                                                */2 Z( |  Z+ l. H* E
  967. /* This procedure checks to see if WEL bit set before program/erase.        */: c6 i% H  C& q( g. P
  968. /*                                                                                                                                                */( G/ E8 g! _8 S& l6 t& h/ B4 o
  969. /* Input:                                                                                                                                */. R# Z: S( `. g+ }
  970. /*                None                                                                                                                        */
    * R! k9 `1 L& v
  971. /*                                                                                                                                                */
    8 u) L6 G  e& M3 V
  972. /* Returns:                                                                                                                                */
    + n/ q3 e" F8 h4 {5 _* C
  973. /*                Nothing                                                                                                                        */
    # v6 x" |6 T- q2 `6 [% x/ P& ]
  974. /************************************************************************/( m6 C0 j' _7 u! A
  975. void WREN_Check(). o: J4 ]' @, d7 \. i
  976. {0 u( ^- g( h% D, T. R- _# Y
  977.         unsigned char byte;( g" G: c- t0 b
  978.         byte = Read_Status_Register();        /* read the status register */" x6 E& [) ^% l7 k- ?8 E
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    6 u- N9 i, n% `% u* a7 P# y' A8 K$ t
  980.         {
    " Q4 P% |* M2 b% x3 S
  981.                 while(1)
    . L7 N' C. _) F5 B7 o+ u
  982.                         /* add source code or statements for this file */9 J9 U6 C; P4 |" T* N* \
  983.                         /* to compile                                  */
    # J% r4 g$ c* L9 i8 p
  984.                         /* i.e. option: insert a display to view error on LED? */
    5 [0 S0 |  U/ J- a- j
  985.                  ) Q  x* o/ c! {9 p, q
  986.         }$ |5 q$ }0 R$ z
  987. }- Y" j. f* C/ f& U  y7 ~! D4 ~

  988. / ^; i* p& ?  K7 ]2 }
  989. /************************************************************************/4 Q+ j3 W* a6 Y3 j
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    7 y1 Q! _( J, n( v/ R
  991. /*                                                                                                                                                */) s' l: n) n' s+ D
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    + k' g4 l0 c" h; ^
  993. /*                                                                                                                                                */
    ' _* D9 `* A7 l. n# Q* p. `
  994. /* Input:                                                                                                                                */) k9 }+ n4 a. \# V- q  X) E
  995. /*                None                                                                                                                        */, C( Q- Z  s7 O% f
  996. /*                                                                                                                                                */
    % x/ M3 z! i. L9 e
  997. /* Returns:                                                                                                                                */# K9 R% w& Q5 i( c0 k
  998. /*                Nothing                                                                                                                        */3 q3 |$ I/ `1 ^9 e" J  e) S& g7 k
  999. /************************************************************************/
    $ d; O& T4 w6 R6 f7 ?( A2 [$ M
  1000. void WREN_AAI_Check()
    5 r/ k* H, `' m
  1001. {6 s: |7 \& T: @3 A  e: e4 P
  1002.         unsigned char byte;; P' E/ V% z3 D" U
  1003.         byte = Read_Status_Register();        /* read the status register */! K, A  v: C5 G1 s, x8 x& s
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    & V4 A' Y: F( }. a$ J0 S
  1005.         {
    & U6 c9 j) J7 z9 F
  1006.                 while(1)               
    4 h  k& @3 x# [
  1007.                         /* add source code or statements for this file */
    # c+ J+ {; r: v/ K) g- `' l
  1008.                         /* to compile                                  */3 ]9 d3 s& L" M$ Q) J8 u' B
  1009.                         /* i.e. option: insert a display to view error on LED? */
      w. g  P" ]) y2 G6 @0 x1 h) A

  1010. ' I& I- p% M( D" H
  1011.         }  s% V' r( |" k  S
  1012. }5 ~5 \9 x6 i( U# }  U1 x8 |: e
  1013. - o0 D4 q1 S/ Y) I2 Y1 x  d, J
  1014. /************************************************************************/
    3 a7 r5 i- y8 [, [" @
  1015. /* PROCEDURE: Verify                                                                                                        */" N# q0 P/ ^. Q6 l- i% R
  1016. /*                                                                                                                                                */
    / @: V2 k& q: `8 W
  1017. /* This procedure checks to see if the correct byte has be read.                */
    $ Q4 v* \2 @( ^3 C
  1018. /*                                                                                                                                                */( w# y" Y4 v' d3 O- l5 N+ O' s* g1 d
  1019. /* Input:                                                                                                                                */
    # P# H* Q' [  ?/ b: H
  1020. /*                byte:                byte read                                                                                        */7 {& F% v' O8 Y$ Z6 {8 Y: q; [" ]; n
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    1 w& h  a! M0 E
  1022. /*                                                                                                                                                */: w; {3 X  y. `+ L4 N* e
  1023. /* Returns:                                                                                                                                */
    + i. H8 T$ k& {, u( |" N
  1024. /*                Nothing                                                                                                                        */% j8 d/ s1 q% d( l% o. K
  1025. /************************************************************************/* E: Y* t: G' I( e' q
  1026. void Verify(unsigned char byte, unsigned char cor_byte)% W% a, r% i6 }/ A
  1027. {
    2 S2 f% W% e/ Z1 ?$ b
  1028.         if (byte != cor_byte)4 _- u3 k7 G( r) j) z' S. T9 }- C
  1029.         {* Y6 `- B0 E3 Q; R* Y
  1030.                 while(1)
    ; z3 v5 r6 B( Y: W# I
  1031.                         /* add source code or statement for this file */# `- V  ^( q0 B7 k/ j
  1032.                         /* to compile                                  */8 y" X" u( V" {
  1033.                         /* i.e. option: insert a display to view error on LED? */, I" z1 n# t2 H/ P5 ~" F- n$ S
  1034.                
    , ~9 m- p/ a0 y/ s! S& M
  1035.         }) n" N9 o3 l5 j5 K! D+ M; P& W
  1036. }
    , S2 U0 D; ^, L! q
  1037. / W3 X% ~- v8 H

  1038. 8 u+ E. E' \6 N
  1039. int main()
    2 x( X* R. V5 G& p5 R, |/ @- w3 b
  1040. {6 B# C2 n2 ?+ Q
  1041. ' F' v: E) U- z
  1042. return 0;
    6 x5 e! Y6 t1 g' [
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
2 D0 w, G% [6 v   main()
  D6 q. I. p0 ]* ]   里面怎么是空的呢?/ ^- a, q  b6 o7 ^0 T
   发一份给我吧
! V6 [3 Q7 n" U- J! Rmail:luyijun2005@hotmail.com* o1 A/ ^0 {2 g# x
咯。。。。
回复

使用道具 举报

 楼主| 发表于 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才能执行。# @8 K; }% D/ j3 h

" l% `! z9 q9 n  ^* t$ A. i[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
( O( C8 Y# ?/ _0 w5 F7 i2 ?/ @' hEC的代码在哪跑,你看DS的说明,每个EC都不同的。
4 H( p# b  C, `, fOEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
4 w% P3 s1 A# D) R3 P2 l  ~+ Q0 A上面几个问题是你没看任何东西而白问。! |4 b( d7 c0 L% o2 T

. \, r& ^4 f/ U至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
' S4 e" s+ m' U  V# ~* c( B- o
+ r2 d: D+ F4 ^" i- \关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!
- |5 Q4 @7 s8 u7 b+ @' J7 W1 s( ~/ t, _+ W" C
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”. N! d, n) u' T- o
0 H4 I/ D# l* k/ L8 N: B: `( ~  q
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...1 r. c1 ?/ J2 {" E5 x
6 O1 h* z; K$ Q3 H; D8 `8 E) J! U
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
+ S3 y) i  o* r5 l- f4 X似乎要把SPI能support 到最大,这EC chip应该有好卖点
! Y: ]- T/ u, [# ?# E6 ABIOS功能要不要强大,也就决定了SPI Flach的大小  c( q& o7 G0 p$ [- }  w
我是这么想的~让OEM去决定要挂多大!
1 A& C* w! J5 i如果我司有BIOS工程师就好了~哈& P5 S- i% |' G: x
WPCE775应该算很新的东西,来看它支持到多大?
! B4 g: s8 _4 Z) Q& [! @
' F0 ^" }; V6 ^另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte- X/ S* L3 u, h" |
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.7 D3 r; j* [+ x. H
5 W! C  Z+ o( I; A" A* }4 C' {: d
这份driver收下~希望以后有用到( i# a7 j/ d* C8 Z7 b3 Z
谢谢bini大大
' x- y$ U! x& c3 Q7 G$ X
  b9 O/ x  r- ?" _) o1 a' \9 L很新很新的新手,如有错误请指正 (准备看第二家的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()4 [" r0 o' P3 Z; _. A0 X7 ^6 y
{: j- Q" H/ \5 S# Z
        unsigned char temp = 0;
) S4 |0 y( P4 W% R% {! r# j: Y        CE_Low();7 v/ v/ L3 o0 u
    while (temp == 0x00)        /* waste time until not busy */
' p1 Y! H  N$ B4 t6 r                temp = SO;
; X/ H. N9 E9 ^  U# i        CE_High();: O/ E, D7 d6 G4 p" _! W
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)6 Z+ b' y" A! i+ c( k
{
9 [% V" C/ j! O: g7 Y( o, ^9 l3 v        
( J/ Z4 n, v3 S: m& _/ d        unsigned char i = 0;7 u" q* w, b& F' w' v' T
        for (i = 0; i < 8; i++)$ O  _3 E' G' ?  s9 X; |
        {; q) D. P+ q; n4 @% q
                - V, U( o& x4 i
                if ((out & 0x80) == 0x80)        /* check if MSB is high */: l8 @* {6 M0 O3 j
                        SI = 1;2 m+ w" y  Q  e+ D4 l
                else
7 J" Y/ `# M/ p- W) J# E. r# h                        SI = 0;                                /* if not, set to low */7 q3 r5 A$ z+ H2 u7 R
问              SCK = 1;                                /* toggle clock high */5 e. c* s: Z  ], g, ?
   题            out = (out << 1);                /* shift 1 place for next bit */
+ G, f* {9 S7 Y' |8 [0 G3 X/ i! |                SCK = 0;                                /* toggle clock low */
2 m: r+ W* H7 y4 p        }' l7 W& x" L$ x7 t. W% c* k: E
}" }; F% R. E) R. A
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-17 17:27 , Processed in 0.229360 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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