找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 52455|回复: 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/ [9 u0 W4 H! p4 G4 |: F8 ^+ Q- F9 t
  2. 4 S% e1 v3 [- x" z
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory0 g4 {# N- R. K+ W4 G
  4. ! O: b+ Z8 |& U& X8 f' X
  5. November 4th, 2005, Rev. 1.0
    6 G  w; Y" n' z; }  j' @$ E/ _/ k( P

  6. 0 T6 U' \9 p8 [9 Z) P
  7. ABOUT THE SOFTWARE
    ; i+ s$ D6 M0 @; q0 c( P2 u
  8. This application note provides software driver examples for SST25VF080B,
    # H& t1 ]2 r) {2 v* a# F
  9. Serial Flash. Extensive comments are included in each routine to describe
    ; H" [. a* Y" V+ m
  10. the function of each routine.  The interface coding uses polling method
    9 |- J$ S" _4 ?! P& m
  11. rather than the SPI protocol to interface with these serial devices.  The
    5 A( p7 W5 P# W% F
  12. functions are differentiated below in terms of the communication protocols
    # j3 @4 ^8 e+ K+ F
  13. (uses Mode 0) and specific device operation instructions. This code has been
    2 I& |7 t9 j  U0 r+ Q1 d! ]) x
  14. designed to compile using the Keil compiler.
    ! w# E- X& C: l2 d1 _: u
  15. 2 g" m; o/ o4 m

  16. 1 z) b2 K3 R' e, i) N0 N+ o( x# N
  17. ABOUT THE SST25VF080B
    ' C1 N' D" x, ~8 `, k  ]
  18. ) i1 A, `3 ~8 _
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    : p8 p. V) a9 k! i- m# {
  20. conjunction with this application note for a complete understanding
    ' a6 N$ B5 T6 @; R# n# v3 l- W
  21. of the device.4 N) W( R* i& s9 J
  22. 6 w& P8 f$ P1 ^7 ]3 w

  23. 1 d6 U, u; U1 j& }* L& [* p
  24. Device Communication Protocol(pinout related) functions:
    # U0 F/ [( l6 H3 {5 Y" r' {
  25. . r4 V& [; k0 {% U* Z5 u
  26. Functions                                    Function. f) f+ J/ w! i
  27. ------------------------------------------------------------------0 h0 n4 |0 B/ S' T5 M+ M  Q
  28. init                                        Initializes clock to set up mode 0.2 d7 J# j! m9 l2 ~/ ~7 H
  29. Send_Byte                                Sends one byte using SI pin to send and + C$ f" Z- [. `9 ^6 s
  30.                                                 shift out 1-bit per clock rising edge% E( P" `( i* [3 ~9 A7 P
  31. Get_Byte                                Receives one byte using SO pin to receive and shift ' H6 s( z  s3 ~$ g5 v' a. K& }6 K; g
  32.                                                 in 1-bit per clock falling edge
    8 B; V/ W1 `- X% X5 u
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming
    . O9 a6 m  V# r7 |$ H) w" v
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    + c1 J; A) s* P  t( o( {
  35. CE_Low                                        Clears Chip Enable of the serial flash to low2 Q$ s+ f* ^* k+ f/ K3 I0 h7 z; P
  36. Hold_Low                                Clears Hold pin to make serial flash hold" z5 I2 p9 V: [( Z
  37. Unhold                                        Unholds the serial flash+ C$ E- ~$ V5 H' t# B9 {
  38. WP_Low                                        Clears WP pin to make serial flash write protected6 [' `' X# S/ L5 o
  39. UnWP                                        Disables write protection pin
    ! L* @2 Y+ A2 [1 j: b/ G7 x' G  h

  40. 9 G- _, l' _  ?0 Y0 e
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    ) Z; D4 h7 n7 J! `) E
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your, D9 ~, q* Z9 j$ g9 G# |
  43. software which should reflect your hardware interfaced.          / N) w3 n9 V) p* @4 |& |% Z' x! O* K

  44. * G3 e& V, m1 [! \

  45. 6 w' j0 \" Z, S, f6 ~
  46. Device Operation Instruction functions:
    7 z. }" p7 Y* ?$ Q$ ~7 \  s, p
  47. & w, U) G) I# l& Y* m4 H
  48. Functions                                    Function
    ( `# M, |, S* m' m& T! Z
  49. ------------------------------------------------------------------  J0 q6 `, H4 [* ?0 S6 V: T
  50. Read_Status_Register        Reads the status register of the serial flash
    ! m, d8 N! x+ A" s; E- `& i
  51. EWSR                                        Enables the Write Status Register, f+ w/ I. w" F  v; V$ m6 {
  52. WRSR                                        Performs a write to the status register
    2 y6 z  P/ Y) Q1 A7 r( e
  53. WREN                                        Write enables the serial flash
    9 i" E$ ?$ D$ e7 {# V  ^1 e
  54. WRDI                                        Write disables the serial flash8 O+ k3 ]/ @; P# l5 x2 \1 h$ p
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming" y" I; f6 t8 P2 b
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming
    ' @% q9 u( @7 y6 W! I4 L  a
  57. Read_ID                                        Reads the manufacturer ID and device ID3 q/ J, L" ^. E6 g/ i
  58. Jedec_ID_Read                        Reads the Jedec ID
    ( e  q5 {* x5 J. z: ~
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    ! b0 F+ [' O6 t
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    ! o; c: c' o4 N* Y
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)" }- U& o* K) x9 o% z0 s/ F- W
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)7 {- `$ H' O9 u0 c5 m
  63. Byte_Program                        Program one byte to the serial flash8 ~: P% g5 Y% ~, k! @
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    4 v9 `/ {/ B1 F+ _) @' G
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation* Q- a9 Y/ u' y# \- y/ A
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    ! v2 k' Y9 M3 h1 I% m( J
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY1 \4 \+ B5 J, v0 K: U
  68. Chip_Erase                                Erases entire serial flash
    8 V3 v0 t8 [' M$ ^
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash. c1 c9 m9 n+ N' @1 }
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    # b8 P, a( S: }1 g3 D+ {$ Q
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    3 L/ v1 r! u- L# Q$ l' y
  72. Wait_Busy                                Polls status register until busy bit is low
    " W1 T& c5 P' {  z% Q; y
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming6 o* L# k( a- J0 f+ D7 K" ]$ }
  74. WREN_Check                                Checks to see if WEL is set6 N' g! D. K/ H6 x& z; {0 t' t
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set3 G) k+ L7 j2 `/ m- ^& G- F

  76. & e$ w7 ]& Z6 [/ G: R
  77.   ^8 D  G3 }  ^/ C

  78. ) l# W3 M" `' E4 I
  79.                                                                      8 b" P0 a  p! f9 d
  80. "C" LANGUAGE DRIVERS 1 v+ U, X: `! s6 ^/ Z

  81. $ V$ M/ W9 g, Y$ F5 N9 h+ `5 p
  82. /********************************************************************/
    5 N5 \2 Q& x7 @: S
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    " h& V! [$ Y( I- h9 H
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */$ Z2 U3 V2 ~/ N3 |3 F7 d
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */( {% w3 W, Y. L5 r% Y( F
  86. /*                                                                  */
    7 B' B1 K# n- J0 T
  87. /* Revision 1.0, November 4th, 2005                                                                          */   2 |: j  T1 y2 I7 I8 \
  88. /*                                                                  */5 J& O. r" _- H& |" L6 j6 i
  89. /*                                                                                                                                        */
    / C; c" A- F9 M  }
  90. /********************************************************************/
    ' ]. j! C* Z: ~8 _

  91. 0 f( W) N6 p* o+ v3 m7 S+ ]& c7 [
  92. #include <stdio.h>
    ! h% l; Q) U  g: w
  93. #include <stdlib.h>
    ' @6 w6 u" Y0 Z% |

  94. 2 E0 _" D" g+ a* w  u
  95. /* Function Prototypes *// p( g, F5 b6 G% X' j2 h7 t- W, h. z
  96. 5 K  z& Z% X# |5 ~- x
  97. void init();
    : W" o4 R- o8 ~  }6 H6 Q
  98. void Send_Byte(unsigned char out);: l& h, \5 C" R" m0 o( _2 V
  99. unsigned char Get_Byte();* t! F, {, b$ O) B  K4 K% d
  100. void Poll_SO();
    0 u' C4 a: J/ R6 F
  101. void CE_High();- t: s4 N" a( f% C7 w, y
  102. void CE_Low();
      N/ f3 l! W0 h- i# d/ |4 |. I
  103. void Hold_Low();
    3 O5 h- n( ~, a
  104. void Unhold();
      e: N3 g4 `6 X
  105. void WP_Low();8 k. [9 |, B0 f3 S
  106. void UnWP();
    9 e& I! F, b+ q" q+ O
  107. unsigned char Read_Status_Register();% n# J% o5 q; c3 K7 u
  108. void EWSR();
    6 Y# Q6 L6 c' b: j
  109. void WRSR(byte);# \( z2 C6 l, O: g
  110. void WREN();
    2 c: e) |% `7 w( ~' B5 z
  111. void WRDI();
    4 g: m) p8 L0 K+ @, p
  112. void EBSY();
    2 t9 A6 R; u+ o5 A
  113. void DBSY();7 ~6 U/ Z( q- S8 z5 U2 f0 J
  114. unsigned char Read_ID(ID_addr);
    # G+ z& W& |; P: L) E
  115. unsigned long Jedec_ID_Read();   Z8 }) P3 w: Z5 D& T3 R6 m
  116. unsigned char Read(unsigned long Dst);% g) b" V9 {8 F2 l9 O. ^, N
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    . C/ {0 {; b% b! u7 ?
  118. unsigned char HighSpeed_Read(unsigned long Dst);
      w6 b2 r: a, G5 @
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    8 A" F: x$ B$ v5 e# X3 Y' D
  120. void Byte_Program(unsigned long Dst, unsigned char byte);4 I3 J3 W) x# R" Y& h2 ]
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);( ~- D- B5 ]  s4 O
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    + U! l' e# t! h1 [2 s- o
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);: W& \7 M$ n% r# D6 f5 y
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
    . s, n7 C* V9 K
  125. void Chip_Erase();
    * W- x" w, O2 _2 @# Y+ x5 g* A& f8 p
  126. void Sector_Erase(unsigned long Dst);
    ' H/ ~) |2 A2 o) N3 K
  127. void Block_Erase_32K(unsigned long Dst);
    5 S3 Z: y5 b1 R! j3 N
  128. void Block_Erase_64K(unsigned long Dst);/ q: _( r5 t5 d5 y$ }: P
  129. void Wait_Busy();3 [& Q6 E, H) O- r
  130. void Wait_Busy_AAI();
    6 @- l# {' O' U
  131. void WREN_Check();$ A' C  t6 W; C) y* O2 r8 k
  132. void WREN_AAI_Check();
    % v+ T- V# w' W- A# @2 E3 H/ Y
  133. 0 d# s6 h5 L: r  G
  134. void Verify(unsigned char byte, unsigned char cor_byte);
    $ y8 [  r8 q: w, K

  135. 0 N0 J; x5 C' A1 L0 `
  136. unsigned char idata upper_128[128];                /* global array to store read data */$ K: r( p$ P7 x
  137.                                                                                 /* to upper RAM area from 80H - FFH */" y: f8 u# B: G6 B! o' }0 `- b1 z8 m
  138. 3 Y: N0 u! I- H" Z0 t
  139. /************************************************************************// f4 V) d! x' ~1 L1 L
  140. /* PROCEDURE: init                                                                                                                */
    , v/ B# l. A' k) M, G, o3 Z
  141. /*                                                                                                                                                */' Y1 i3 b, b& ~$ P1 Y/ F$ G9 A
  142. /* This procedure initializes the SCK to low. Must be called prior to         */
    7 R) P0 X, {& R* M
  143. /* setting up mode 0.                                                                                                        */
    4 N* v# |3 C3 ?3 a4 K6 |/ ]
  144. /*                                                                                                                                                */
    7 Z0 L2 h9 N6 U8 {7 T  r5 t2 x
  145. /* Input:                                                                                                                                */
    - ]+ Y$ {+ t3 h0 X$ c! ^6 o1 K$ Q
  146. /*                None                                                                                                                        */
    & m5 \  e1 T( Z* r7 B8 X: F
  147. /*                                                                                                                                                */
    * v' Z' T1 g( |3 B+ Y
  148. /* Output:                                                                                                                                */
    ; j2 S) V9 }% B
  149. /*                SCK                                                                                                                                */& f4 g6 L; Y5 R6 d' ?7 I, H" F
  150. /************************************************************************/
    5 G  o' a+ L) @% z
  151. void init(), r& w, q+ E7 G! D
  152. {% R& i+ _2 e1 ?
  153.         SCK = 0;        /* set clock to low initial state */0 L) k8 E. L3 L9 P2 [5 A' l
  154. }! s" w* Q4 c7 X8 x

  155. 9 C2 A8 P2 {2 k& a: d
  156. /************************************************************************/
    & J9 n" B& j* _. B) G6 Q
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    " P  r" c. g7 Y3 A* @/ b9 d3 N" x% m
  158. /*                                                                                                                                                */
    4 o8 G: j" B" t; z1 ]
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    ( [" E7 M: n" W# E; P
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    ( l. O: K; P$ F& A
  161. /*                                                                                                                                                */
    & z: [; w" O0 }+ a) q7 i
  162. /* Input:                                                                                                                                */& B, M/ S$ z! E  `
  163. /*                out                                                                                                                                */1 s$ p# g7 w0 z
  164. /*                                                                                                                                                */
    / M7 r9 D4 B) s" |+ l& N4 `( n
  165. /* Output:                                                                                                                                */
      F$ a% o" F# j0 S' g7 S8 [1 D& Y6 c
  166. /*                SI                                                                                                                                */
    ' ^6 ]" V5 n; z" @! W1 u- D" m- R; S# y& v
  167. /************************************************************************/
    ) t: O0 g* A6 `$ |( K( u7 p
  168. void Send_Byte(unsigned char out)
    0 Y* G  d$ M! r  R* a+ Q4 W
  169. {. h  y7 Q/ d/ o1 P
  170.        
    ' h  E7 G. \3 g/ M9 a2 a  b" T
  171.         unsigned char i = 0;- b. [. ]- y$ P) U! |: I
  172.         for (i = 0; i < 8; i++)6 w( e( }+ H3 A
  173.         {
    3 ^$ S9 r& ^$ e! x+ G
  174.                 0 b1 ^! N: t" r6 P: B5 F* d3 U3 r
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */- g7 p; a! @% @2 F
  176.                         SI = 1;
    ' ]  J$ X5 E  T* e: i. S5 D
  177.                 else% G) a2 `0 h5 q( Z) c) A" r
  178.                         SI = 0;                                /* if not, set to low */5 X3 n4 |; s" a" f4 W
  179.                 SCK = 1;                                /* toggle clock high */
    ! p& S9 w4 c3 i" {
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    8 y1 X( u# ~7 ?; ~3 w/ g4 u
  181.                 SCK = 0;                                /* toggle clock low */  W. f! C5 Z7 F+ v) h! |+ k
  182.         }
    ! o$ z% v$ L1 v' }1 m! }2 Z
  183. }& h% ?7 H$ g+ t5 c0 i' m: }6 ?
  184. ( A) e5 H# j/ l# m0 v* e6 d; S5 a
  185. /************************************************************************/" ~# x5 i! A9 q$ |, Z; @
  186. /* PROCEDURE: Get_Byte                                                                                                        */
    $ w5 W, E6 \% B! R
  187. /*                                                                                                                                                */. ?" r# t. _. \/ ^8 i. `, O
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                *// I+ L( h8 U  f( t' t2 e
  189. /* edge on the SO pin(LSB 1st).                                                                                        */
    / q. ]8 ^" E1 P  |
  190. /*                                                                                                                                                */
    * n/ v% [$ r+ F4 W- d; _
  191. /* Input:                                                                                                                                */. k1 ^( h$ ~6 [6 s, f6 x! o; m0 f
  192. /*                SO                                                                                                                                */
    2 X- @+ R3 Q$ e5 F( l
  193. /*                                                                                                                                                */" D/ |3 Z4 V4 x$ h& R
  194. /* Output:                                                                                                                                */6 g! k2 Z3 Z* _: T% T
  195. /*                None                                                                                                                        */
    - r1 R; M" Z7 p  i
  196. /************************************************************************/
    ' Z$ {$ F% s8 d0 H* c
  197. unsigned char Get_Byte()& j1 u" B' k8 n$ M% {$ {% e8 x
  198. {+ r' M' {2 Z( _6 Q/ i# F, E2 q
  199.         unsigned char i = 0, in = 0, temp = 0;
    * U# @& k1 n1 Y/ Q5 f. [$ e
  200.         for (i = 0; i < 8; i++)
    ! j5 L3 I- Q; `! j2 @  _
  201.         {
    * x) N# i& [" z
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */& Q: K* V' d/ J: q# o5 i' k& W8 F
  203.                 temp = SO;                        /* save input */
    : c& ?' X+ J, u
  204.                 SCK = 1;                        /* toggle clock high */" i& D- p5 ^5 O! R% H: W1 y
  205.                 if (temp == 1)                        /* check to see if bit is high */% [  T# E6 v. P0 ~3 r; q. \
  206.                         in = in | 0x01;                /* if high, make bit high */! p4 b6 ~$ ~( i; x8 [

  207.   ?+ S  u8 U' K( i" l
  208.                 SCK = 0;                        /* toggle clock low */
    ! ]2 j. w. y- c. Z9 k/ X
  209. 9 {5 J4 P: X( W: F4 x$ Z
  210.         }
    $ R4 j) |& w5 y8 |
  211.         return in;2 Q3 q8 g, z+ B) z2 X5 f8 m
  212. }9 @5 A5 d  B* x) f) |$ t. i4 l9 ^
  213. 7 N6 k8 P' v( ~$ q+ C
  214. /************************************************************************/7 ^7 a( m+ h9 I( W  g
  215. /* PROCEDURE: Poll_SO                                                                                                        */
      s; Q) y" }$ @3 Q- `
  216. /*                                                                                                                                                */" _8 L9 u- I1 D# X6 [1 @3 g
  217. /* This procedure polls for the SO line during AAI programming                  */" p- Y- J+ k1 R/ c, [
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    6 ^# B; I+ G, I1 D+ _
  219. /* is completed                                                                                                                        */3 J5 I9 J2 F7 [  j2 F
  220. /*                                                                                                                                                */
    / Y9 ]* S& v! r' b) q
  221. /* Input:                                                                                                                                */: ^+ D% M4 x/ R
  222. /*                SO                                                                                                                                */: z7 s) Z$ G$ H* e
  223. /*                                                                                                                                                */
    6 s, v) c  |  [1 X: _( t# e
  224. /* Output:                                                                                                                                *// f, {( ~+ Z8 x6 @8 S& o
  225. /*                None                                                                                                                        */" ^: _( E( S0 L9 H/ }; H
  226. /************************************************************************/
    ) r' Z8 w# [7 k* h
  227. void Poll_SO()
    5 S% W' h4 v4 c+ g+ ~2 I
  228. {- j7 o( u2 \8 C( i8 w
  229.         unsigned char temp = 0;
    , j: ]; K8 J% E. K$ u* H
  230.         CE_Low();
    1 \' z& a- `8 N0 n0 G6 U0 j
  231.     while (temp == 0x00)        /* waste time until not busy */! i( q2 b9 ]+ t% ~- Y8 t3 N/ j  E
  232.                 temp = SO;+ z+ F& g% {% X! w, ?
  233.         CE_High();& g& Q5 n. e) S/ Z+ ~
  234. }
    5 J( w* O/ r( s% i8 U0 n

  235. ( `3 L; w0 T$ z3 b) d
  236. /************************************************************************/# `9 B: N/ s" D- T0 \
  237. /* PROCEDURE: CE_High                                                                                                        */
    # q8 _/ b1 I" P1 A+ U
  238. /*                                                                                                                                                */1 [. _7 z3 c) b/ {) ]
  239. /* This procedure set CE = High.                                                                                */
    ' R+ B8 s, t& r9 s$ C: f4 z; L
  240. /*                                                                                                                                                */
    / w% t# N2 C2 j" L
  241. /* Input:                                                                                                                                */
    * Z+ }' H8 e' f7 t- C6 S
  242. /*                None                                                                                                                        */9 Y  ^9 y6 b5 ^2 J5 H  j9 X
  243. /*                                                                                                                                                */; }5 r! J( F9 P7 T$ R. P( d% _0 G
  244. /* Output:                                                                                                                                */
    & r: ]; w, P5 M0 m
  245. /*                CE                                                                                                                                */& u( U! |: ^9 J# I1 g
  246. /*                                                                                                                                                */
    6 {+ t, C  v' |) E3 ?6 }
  247. /************************************************************************/' |/ Y  c. x' i& [# ], @1 A
  248. void CE_High()
    - @, T8 d" J+ n) n# q% j
  249. {1 D! C4 G, @% F6 S
  250.         CE = 1;                                /* set CE high */0 U; D" i* g% o. n
  251. }
    2 c1 p- f" H" j8 _, x8 @
  252. ! Z" B) o1 Y) f% \  `& t
  253. /************************************************************************/
    0 p7 B% _: u- }5 V: W
  254. /* PROCEDURE: CE_Low                                                                                                        */( t. `: D9 ?& y+ L. T/ Q# O
  255. /*                                                                                                                                                *// k$ x( ^$ ]7 m! q5 W" O
  256. /* This procedure drives the CE of the device to low.                                          */
    4 b4 Y9 t) H& J
  257. /*                                                                                                                                                */, ^; M7 b9 G( I/ w( y+ c! `' v0 y
  258. /* Input:                                                                                                                                */! ^) V+ |$ z1 h3 V) I
  259. /*                None                                                                                                                        */+ I3 }8 [7 A, y. z
  260. /*                                                                                                                                                */
    4 n/ G9 B1 H$ J' T5 |0 j$ c% e- z, t
  261. /* Output:                                                                                                                                */- U* C7 @6 h9 R  I
  262. /*                CE                                                                                                                                */) x7 n# {* C! d8 `: s4 G' ]
  263. /*                                                                                                                                                */7 Y) k$ M& I! f8 x' [# L8 _) ]+ V
  264. /************************************************************************/( e9 q$ D1 ?7 F9 _6 Z; `8 D
  265. void CE_Low() * E8 `# T  s' O* @$ t, x) L
  266. {       
    : u3 ]/ L  j4 k
  267.         CE = 0;                                /* clear CE low */
    6 f' Z( H: y: H6 t# ]" H
  268. }3 }% N+ c* u; y# F; o
  269. * f1 @/ n2 |) [; D, ?* \3 C' ?
  270. /************************************************************************/
      X( W- y8 m9 v0 ~! w3 c
  271. /* PROCEDURE: Hold()                                                                                                        */! y' Y! B) z9 s$ [; F( @& W
  272. /*                                                                                                                                                */
    ) Y, s% [  r$ d9 W- @! U
  273. /* This procedure clears the Hold pin to low.                                                        */
    $ }8 Y9 e5 }: X' S: Z* ~: _8 ~* `
  274. /*                                                                                                                                                */
    & H+ h( V1 N" c3 H$ e3 C
  275. /* Input:                                                                                                                                */
    , c1 {6 b5 l/ ^- y
  276. /*                None                                                                                                                        */
    ! z) N0 M0 p# a- ?  ~
  277. /*                                                                                                                                                */" H. ~! y) ]1 R2 N* v
  278. /* Output:                                                                                                                                */
    / L+ L1 s3 H/ G, g) b
  279. /*                Hold                                                                                                                        */
    / N, v4 F; X* {8 a' x3 e# K
  280. /************************************************************************/9 U$ d9 g" ^* k4 @- v$ F2 C
  281. void Hold_Low()% @/ f2 E. f8 S& [( j
  282. {
    $ V% @$ w$ Z6 Z
  283.         Hold = 0;                        /* clear Hold pin */
    3 n! n) R% K; j! i; X$ w
  284. }$ y. E. x6 q2 @0 Q
  285. ! _" y7 B9 n( _5 h! F% w/ H
  286. /************************************************************************/
    : a* |9 G7 o4 u. A  R5 O
  287. /* PROCEDURE: Unhold()                                                                                                        */3 u- T. n6 g$ b* H$ Y# B
  288. /*                                                                                                                                                */
    : d3 d3 Z+ d% G2 N
  289. /* This procedure sets the Hold pin to high.                                                        */
    ; ?; S& F: d8 D: e* k( b
  290. /*                                                                                                                                                */: Q5 l4 J' d, L+ y: Z( g
  291. /* Input:                                                                                                                                */
    ! l$ o, k* [& r3 S- i
  292. /*                None                                                                                                                        */
    5 D- S; u+ M3 G6 J( ~0 T+ [/ T) q
  293. /*                                                                                                                                                */1 q' r4 C+ {3 i4 I' @4 B( c
  294. /* Output:                                                                                                                                */
    4 \$ H% h1 U) X
  295. /*                Hold                                                                                                                        */
    ' q+ ^2 Z( _3 G3 m$ E/ B
  296. /************************************************************************/
    . J% i" z- E' D6 {
  297. void Unhold()
    5 E2 a" p/ d4 S9 E! |$ ?% P, [
  298. {
      \1 `: ], h2 A6 c) _/ K7 R
  299.         Hold = 1;                        /* set Hold pin */
    * n. H' u  d  b8 ?- e) e( |* j1 i
  300. }
    / I$ }/ h! f; |+ Y: p( g7 U

  301. , V. d% C3 S0 z
  302. /************************************************************************/: v; H% @$ [; u# b
  303. /* PROCEDURE: WP()                                                                                                                */" |/ w, m8 p) K2 `4 J  F
  304. /*                                                                                                                                                */
    # h% t1 Z. s' a  H( Y$ A
  305. /* This procedure clears the WP pin to low.                                                                */
    , k  c! O9 Z# b) y( N
  306. /*                                                                                                                                                */6 F* |9 j8 [6 a  \4 H9 X
  307. /* Input:                                                                                                                                */2 \" j/ @- C& G/ m: ]
  308. /*                None                                                                                                                        */
    9 G3 L6 V+ D; @2 I2 }  ]  F$ B
  309. /*                                                                                                                                                */1 @, e  r9 i, \% m8 H
  310. /* Output:                                                                                                                                */
    8 p! M+ D! J" B- _& b  N1 w
  311. /*                WP                                                                                                                                */" p  a1 ]$ J, {( J7 J9 y# G
  312. /************************************************************************/
    # N8 h9 B$ L5 Z5 e2 K$ `( l: H( A( a
  313. void WP_Low(); ^( l: v8 R0 k# i2 Y
  314. {& m7 L! Q' C) b2 ?' `
  315.         WP = 0;                                /* clear WP pin */1 z5 H$ E# O$ |, U5 u
  316. }/ K. R2 h# c8 f& b2 J

  317. ; G* J0 d9 a; Z% v+ F4 k
  318. /************************************************************************/) Y, g7 k  N9 n$ n) U9 }* c' I
  319. /* PROCEDURE: UnWP()                                                                                                        */- d. k7 I: l7 O( l# a- Y7 _  S
  320. /*                                                                                                                                                */
    + `5 C8 A3 d$ @- D% [
  321. /* This procedure sets the WP pin to high.                                                                */
    $ [4 _  e- e0 M7 E& F
  322. /*                                                                                                                                                */
    9 K4 E+ G3 [  T+ [
  323. /* Input:                                                                                                                                */$ v. C# i3 f, a9 b1 B& D7 h) q0 N
  324. /*                None                                                                                                                        */% B8 j6 e% A% o, W  R5 I8 j2 n4 K
  325. /*                                                                                                                                                */$ x1 P3 i! P# W. G  Y% i
  326. /* Output:                                                                                                                                */0 T- Y4 c3 Z  G& b5 A4 _7 o* V
  327. /*                WP                                                                                                                                *// c$ _. ]: d1 J" s: i1 U, K: M' x
  328. /************************************************************************/9 u5 i' G" o. |& }8 ?" U
  329. void UnWP()
    ) p) f* |/ U( t4 u6 M# ?
  330. {7 k- u" |+ H1 j
  331.         WP = 1;                                /* set WP pin *// A; Z$ a6 M/ k. v, ^2 f
  332. }
    , w! B8 g% y! o7 `4 h' S* j

  333. / Q. ^( l% E/ ^5 I
  334. /************************************************************************/# W+ T8 K& m  A9 q
  335. /* PROCEDURE: Read_Status_Register                                                                                */
    - H+ b( `0 z6 Z. z& b7 `8 q* r
  336. /*                                                                                                                                                */
    ! Z% z/ x8 h& t* b  u% Y  b
  337. /* This procedure read the status register and returns the byte.                */8 `! C# b3 Q7 @8 z. I' q9 `
  338. /*                                                                                                                                                */
    * p: Y; V1 t! a
  339. /* Input:                                                                                                                                */
    " S: L! m8 U5 y& A9 k/ l! j" q
  340. /*                None                                                                                                                        */& i6 O" x' C* R; E
  341. /*                                                                                                                                                */2 v! w4 s/ W$ H3 H
  342. /* Returns:                                                                                                                                */' j4 ]: W% }/ V% ~6 s
  343. /*                byte                                                                                                                        */
    2 J  s  g' O7 t+ i. Z1 W2 ~7 M
  344. /************************************************************************/
    # @# U+ J$ `3 u1 y1 ]
  345. unsigned char Read_Status_Register()* B& N' E2 r, o. J8 L1 F% B
  346. {
    : ~6 J& y% I5 `3 h2 p- F9 c
  347.         unsigned char byte = 0;
    : w2 Q& {* c7 _
  348.         CE_Low();                                /* enable device */( z9 O1 x/ D3 W1 o
  349.         Send_Byte(0x05);                /* send RDSR command */
    " X3 w% u* ?- q6 x, C
  350.         byte = Get_Byte();                /* receive byte */7 I8 ~. R0 U: t- T' K; q
  351.         CE_High();                                /* disable device */) @# u! y/ `* N/ x6 F! L
  352.         return byte;
    ; y+ m6 a1 l+ i
  353. }
    : _( `3 z+ b1 Q) I: f6 ~7 W& _; f
  354. 7 b7 U8 w+ ^) c) h; a; A2 K
  355. /************************************************************************/
    8 O7 h2 X# F9 `  i
  356. /* PROCEDURE: EWSR                                                                                                                */8 M2 b! I2 F# n! x' D9 l4 R' n
  357. /*                                                                                                                                                */* V& B4 Q7 q. _4 U# P8 G
  358. /* This procedure Enables Write Status Register.                                                  */
    / a( s. ]5 A3 b7 q* m/ f
  359. /*                                                                                                                                                */
    ) D3 r4 C3 M3 P9 G+ T4 ?
  360. /* Input:                                                                                                                                */! I9 L0 X# f: ^% A/ P* \. G
  361. /*                None                                                                                                                        */
    . {; H+ V7 L; D  b% d
  362. /*                                                                                                                                                */
    9 G  m! C) I$ I6 e; d2 B( U" }
  363. /* Returns:                                                                                                                                */8 w2 p" h4 _5 |: U- A3 S
  364. /*                Nothing                                                                                                                        */
    , h1 y; D: H; M6 p: }
  365. /************************************************************************/
    9 Z( {, t) w+ ~, R/ u
  366. void EWSR()  }4 v6 a; }/ x0 @0 Y/ ~
  367. {4 {3 J: ]% M1 U" p+ {7 f6 Q/ A, i
  368.         CE_Low();                                /* enable device */- S0 a3 x* M" L$ g: x
  369.         Send_Byte(0x50);                /* enable writing to the status register */  Y8 D# G1 R3 P8 Q
  370.         CE_High();                                /* disable device */
    * [7 M+ Q9 y/ ]" K" E2 v
  371. }
    ) U5 _4 C$ O! J7 L/ f
  372. + k- `, N# f) A; g. B# g
  373. /************************************************************************/7 m5 W' Q: R( e! B# T0 B
  374. /* PROCEDURE: WRSR                                                                                                                */) N+ P  c% b" ~3 V
  375. /*                                                                                                                                                */) r4 |' L2 D' ^3 D
  376. /* This procedure writes a byte to the Status Register.                                        */
    5 i& r3 f% Q$ ?- i
  377. /*                                                                                                                                                */% D! x3 W+ h: a5 X+ z6 ~
  378. /* Input:                                                                                                                                */1 {- f0 n8 A8 O* P2 D* k1 c
  379. /*                byte                                                                                                                        */
    ( T; }- z0 J5 m& c4 j
  380. /*                                                                                                                                                */
      a; C! b/ r0 X
  381. /* Returns:                                                                                                                                */6 Q6 U. ^. ]4 Y! [/ Q
  382. /*                Nothing                                                                                                                        */* w+ \4 w% A% j6 X
  383. /************************************************************************/4 `# ?8 W5 H1 |6 ?) U; R
  384. void WRSR(byte)
    6 d& ^% G+ g+ W- m
  385. {: U2 k: z* B' P) y! l/ x* k3 [! i
  386.         CE_Low();                                /* enable device *// J' ~( ^, n3 @& |. M3 M- W; a
  387.         Send_Byte(0x01);                /* select write to status register */
    # E4 r& n/ y9 T1 i! C/ y; @# B& t6 s
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    ( M# i1 t5 q( {% X
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    : Y3 |3 y" q8 }' ^! s
  390.         CE_High();                                /* disable the device */! E& C6 q' l& F. l* s0 U" {
  391. }/ s7 N) o; Q  o6 o9 G" b
  392. * A! ^0 t9 l, |% E
  393. /************************************************************************/
    3 A3 u- t/ F1 Y5 \! @* h4 @' L
  394. /* PROCEDURE: WREN                                                                                                                */
    ) E, y0 O4 P- ^' V$ _
  395. /*                                                                                                                                                */+ o$ v2 E$ A! N# m% G+ h* o
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */, P4 A  ]% T/ ~% G" t
  397. /* to Enables Write Status Register.                                                                        */) j  N( q+ r5 H4 K+ v
  398. /*                                                                                                                                                */
    ! }) i$ N' O7 N7 E3 ~3 e) ?3 [% e" y
  399. /* Input:                                                                                                                                */
    . A+ r+ @/ d0 b# B2 w
  400. /*                None                                                                                                                        */4 R( v8 H/ C" T& S: {0 w5 f, i) [
  401. /*                                                                                                                                                */
    0 a6 l3 {" n/ C- c$ p
  402. /* Returns:                                                                                                                                */
    1 Q1 R2 L* K9 i+ P
  403. /*                Nothing                                                                                                                        */; [  d( P* i& Q$ q4 O8 `
  404. /************************************************************************/
    9 b. M5 ?" j% I/ J9 X9 q
  405. void WREN()
    3 l% o7 ^; `1 c/ ]5 T. C# u1 Q
  406. {
    - E' O% S* y$ N' j) H, D( j
  407.         CE_Low();                                /* enable device *// X+ b' k+ K: C0 d. ~& k
  408.         Send_Byte(0x06);                /* send WREN command */1 @( ~) u% N$ L
  409.         CE_High();                                /* disable device */- f* I' q& B1 O8 f  _6 i: @6 _
  410. }
    / `5 f, T+ H& s7 h; [; m" _  F! `

  411. , r3 X' ^1 [  E1 w* [  x# y9 M2 i
  412. /************************************************************************/$ U! ~% f% ^2 g/ O9 t
  413. /* PROCEDURE: WRDI                                                                                                                */* |8 @! ?8 Y3 u0 J# H* P' X8 v
  414. /*                                                                                                                                                */
      b* P3 r7 d' f' K
  415. /* This procedure disables the Write Enable Latch.                                                */
    4 W- ], K5 Q6 Y# D0 ?5 Z
  416. /*                                                                                                                                                */, F- V3 }8 W! L7 p" |0 E
  417. /* Input:                                                                                                                                */
    : J/ U' b2 n  u: n( c* h
  418. /*                None                                                                                                                        */
    6 X: _! i1 L, n9 a) L7 v
  419. /*                                                                                                                                                */, k8 s! R$ q6 n# @5 @
  420. /* Returns:                                                                                                                                */
    3 \" y" {( }  @/ A
  421. /*                Nothing                                                                                                                        */
    $ y* W/ a* z2 [' x' j4 L: a& p- i( T  V
  422. /************************************************************************/
    5 [) a' F! d2 k1 b6 z
  423. void WRDI()
    & u" s& b  N# y7 f# J/ u# Y9 b
  424. {: d, y- G( `! N( F4 {
  425.         CE_Low();                                /* enable device */# M( X: Y6 W- U: c5 ~
  426.         Send_Byte(0x04);                /* send WRDI command */
    3 z# n( ~" N; V+ R* Q
  427.         CE_High();                                /* disable device */
    3 B7 Y/ l4 @5 ?/ y3 ~3 d, l) Q6 e
  428. }
    3 j4 w2 z2 Q2 X1 X( e* B7 B" }

  429. ) B& ]' l* \/ m, G3 {" _4 a& r
  430. /************************************************************************/. w4 ~5 A" G1 O! Z" m% M" i9 {
  431. /* PROCEDURE: EBSY                                                                                                                */7 r4 q" ]* U: Z6 b" Z/ M" J1 ~
  432. /*                                                                                                                                                */
    0 k1 ~/ H* M# y3 l1 v7 h9 Z
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */( ^9 o7 J6 y, W5 Q( p( m- w( N
  434. /* programming.                                                                                                                        */4 x1 |0 m8 n" I/ [5 F
  435. /*                                                                                                                                                */0 T' U( t; v: S; r
  436. /* Input:                                                                                                                                */" p# X$ X) K2 b4 B
  437. /*                None                                                                                                                        */
    * i6 E/ E( N/ k+ B% j- E
  438. /*                                                                                                                                                */& {# p4 ~5 z2 \2 |
  439. /* Returns:                                                                                                                                */7 G: l% R/ F% f' v0 V5 ?* |; P5 c/ S
  440. /*                Nothing                                                                                                                        */
    : Y/ l/ F/ t. g5 a
  441. /************************************************************************/' \/ l/ J. w2 A, w* Q1 O
  442. void EBSY()" \+ W& j/ i3 X
  443. {
    # Y1 g* Q, h3 U, {
  444.         CE_Low();                                /* enable device */0 }5 c3 L- d2 k2 O
  445.         Send_Byte(0x70);                /* send EBSY command */
    / N9 E8 N6 E$ R9 V, y1 |1 D/ f+ J
  446.         CE_High();                                /* disable device */
    2 ]  d0 x) J6 l! @
  447. }
    & N0 H6 j8 w  p* G

  448. 1 L/ f- l& g" e; Q& i
  449. /************************************************************************/
    5 e2 k7 Y. v& m) K* \. X! T  n) T( j
  450. /* PROCEDURE: DBSY                                                                                                                */6 f. R: {1 u* M( d4 N3 Q+ C4 w; e
  451. /*                                                                                                                                                */( F9 o; y$ q2 g; N' h
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */; u% \3 q; ^# g! Y; L$ ~8 T! v
  453. /* programming.                                                                                                                        */
    - b& {  n$ ^) h) e, n7 D
  454. /*                                                                                                                                                */; H( U# ]4 H7 A4 Z: ]% [# x
  455. /* Input:                                                                                                                                */! H5 T7 s1 ?1 S; v0 b0 j) T/ X
  456. /*                None                                                                                                                        */
    # g) t0 ~* a2 O. i1 I( ?$ T3 p5 U
  457. /*                                                                                                                                                */
    ( }! B7 ~7 w* J
  458. /* Returns:                                                                                                                                */7 ^2 l7 X6 e* J6 j; S. \. A
  459. /*                Nothing                                                                                                                        */
    3 M% R4 X2 C$ J1 D& K' [0 ^+ t
  460. /************************************************************************/
    + J- }3 p% @; h. x! X
  461. void DBSY()
    , ]! y  v( @8 G
  462. {9 k! H9 G/ \; C0 X+ m: l
  463.         CE_Low();                                /* enable device */
    & ^# n4 x# E0 `5 o- e7 C* z0 U3 @
  464.         Send_Byte(0x80);                /* send DBSY command */
    8 X9 a2 \' K, x3 j6 S
  465.         CE_High();                                /* disable device */
    " n& Q, D1 `) o% g
  466. }. [! _1 S# w, Q; g
  467. 0 I) f/ |4 T2 b* J
  468. /************************************************************************/
    . H, ]& u) [$ z! l& `: k8 ]0 x4 |
  469. /* PROCEDURE: Read_ID                                                                                                        */$ P) v* H' F: ]& h' r$ T8 H2 [
  470. /*                                                                                                                                                */
    / f, D1 v& M+ B% Y: S1 q
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    7 B9 l# @, Q6 u9 ~. J' M: w
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */" n& ~& x- ?" d  N: Y: _& U
  473. /* It is up to the user to give the last byte ID_addr to determine      */
    4 G  X5 I. a9 M4 Z
  474. /* whether the device outputs manufacturer's ID first, or device ID         */
    0 F9 O) A: @' D1 {2 v* X
  475. /* first.  Please see the product datasheet for details.  Returns ID in */4 f- C) {  F, T, R- i
  476. /* variable byte.                                                                                                                */
    ' p0 o$ j1 |9 D0 T- `7 D/ @- Z
  477. /*                                                                                                                                                */
    1 _2 {. R, ~6 {; }$ {
  478. /* Input:                                                                                                                                */9 E4 H2 Z4 f& Q# L7 i4 v
  479. /*                ID_addr                                                                                                                        */8 Z. H8 |5 I% `+ A9 X5 v
  480. /*                                                                                                                                                */
    8 V- }  Z: ]2 o/ T7 Q1 q; D
  481. /* Returns:                                                                                                                                */' v- Y  L% y+ Q3 d; c5 |! W0 L" E
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */: F1 H3 ~7 R; @3 p8 M
  483. /*                                                                                                                                                */6 ]( D% P" C! J9 b# a1 c
  484. /************************************************************************/& v+ e; x( K" P6 \' K! X2 n
  485. unsigned char Read_ID(ID_addr)
    ' f' b3 t* f) H% y+ `2 O
  486. {, u! @+ Q5 p5 L8 P
  487.         unsigned char byte;" F2 {6 @  B5 [, ^
  488.         CE_Low();                                /* enable device */5 z- b) l# m: a/ g
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
    3 d) s$ b6 r/ ]: o/ @# u% R% S! V
  490.     Send_Byte(0x00);                /* send address */. S1 s6 M: U, U8 a9 B4 Z( }7 @
  491.         Send_Byte(0x00);                /* send address */
    & t) d9 Z/ E7 Y3 \+ `6 f- E
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */9 W8 D* O' h9 s' }) Z% d
  493.         byte = Get_Byte();                /* receive byte */
    6 o; T3 U( s9 J8 @3 e5 |. l) S7 c
  494.         CE_High();                                /* disable device */
    1 M7 i( C* |  _. P7 [. V
  495.         return byte;5 Z- P1 u) F* M  C" c9 l
  496. }
    0 u; i) N4 Z/ j& f" @" z

  497. 8 o  r* |# y% M: _' F+ T/ }
  498. /************************************************************************/$ x* X1 h* ~5 [4 ?2 w
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */
    ! B2 R. N3 K( K4 r# x6 J8 s; U) M
  500. /*                                                                                                                                                */
    % a& U) m. Q0 }& H
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */
    - K. l! b1 }  W( G( Q6 n
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    ' L9 ~9 `: y8 L
  503. /* Please see the product datasheet for details.                                                  */' D$ i' X+ N& X5 v+ c3 x9 Z; Q- |
  504. /*                                                                                                                                                */  X& l" O7 N' b8 H
  505. /* Input:                                                                                                                                */
    8 L* T5 p: j9 A5 U1 ~1 n! V
  506. /*                None                                                                                                                        */" L1 @; \- X( g, l8 S
  507. /*                                                                                                                                                */8 M9 l' a7 A$ R9 I2 |& Q5 `4 _
  508. /* Returns:                                                                                                                                */# j* w5 e6 l# ?' X: M2 [
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */
    # J' Q3 P: i4 J8 a/ L, {- ?* Y% P
  510. /*                 and Device ID (8Eh)                                                                                        */
    4 w7 c/ v( q, W" |
  511. /*                                                                                                                                                */
    # }: K# t6 x5 b/ e) [
  512. /************************************************************************/6 `  e0 G7 ?- F) x: r) p$ z! j
  513. unsigned long Jedec_ID_Read() 7 A. D) h- D+ k& `
  514. {! k7 u* x* u  C  K$ |! Z6 d
  515.         unsigned long temp;
    0 S! e, U" ^) r& e
  516.        
    0 e" T2 X8 V& h, A8 B$ S  ]; o
  517.         temp = 0;
    2 W1 t3 F  J7 a/ r

  518. + ~, E; F4 P+ o6 g" e1 F! O" @& w
  519.         CE_Low();                                        /* enable device */
    . ?6 s! \! H3 U# u# h1 O2 V
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */& |( d- w: C4 |+ y$ U$ Q  g
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */6 s9 h7 C( ^  `; ^: ~. J" U' p
  522.         temp = (temp | Get_Byte()) << 8;        5 G7 ^! j1 u* C6 z) b- ~! D/ u: P
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */) E% L( P1 e7 _  E0 k8 C2 c1 O
  524.         CE_High();                                                        /* disable device *// Q" c" w, ]5 w. z/ ^

  525. ) W8 q" S6 ?: N$ n
  526.         return temp;
    ; u" a( E# S# k2 L) ~9 q
  527. }$ \. G8 W; A' k9 q9 t" _5 e

  528. $ k! u: S* P6 `4 ^
  529. /************************************************************************/
    8 v  a! ?2 w9 V, _; C* K; Y9 w7 _
  530. /* PROCEDURE:        Read                                                                                                        */
    7 |; c- w4 j/ w: i' M8 _$ t: f: C
  531. /*                                                                                                                                                */               
    ; F5 i# @7 Z) G( n+ O
  532. /* This procedure reads one address of the device.  It will return the         */- X' N% X( I6 G
  533. /* byte read in variable byte.                                                                                        */$ Y; _3 W! R0 \% i7 ^, G
  534. /*                                                                                                                                                */* u0 N1 y) w* J4 n$ q* B5 B' l( g
  535. /*                                                                                                                                                */0 X# G: w5 m, b  a5 ?
  536. /*                                                                                                                                                */; A& }8 Z: Y" S+ Y. I5 |
  537. /* Input:                                                                                                                                */
    / y, K) N5 D0 H- @# _/ z, D* Z
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */* v; S4 [: Q* n9 k
  539. /*                                                                                                                                      */
    $ L' l8 e% U7 ~# a8 h4 k
  540. /*                                                                                                                                                */0 _' z' }( q* e3 v
  541. /* Returns:                                                                                                                                */- p4 g! I) I7 ?- c
  542. /*                byte                                                                                                                        */9 \' _4 }1 _' r( S/ p! A9 e' X' u
  543. /*                                                                                                                                                */# N3 ?9 f" ]* r9 M. _
  544. /************************************************************************/
      T$ v8 K, s- _* ^! {
  545. unsigned char Read(unsigned long Dst)
    9 R2 ?. t4 M* q, N5 ?
  546. {7 C: |7 [5 Z3 S9 n& n- w9 k; T3 c
  547.         unsigned char byte = 0;       
    - l* q; E% j! e/ E& Y
  548. : ]& f' X. ?- n6 S% n
  549.         CE_Low();                                /* enable device */
    8 {" p9 v+ Z8 z+ _" h3 \
  550.         Send_Byte(0x03);                 /* read command */
    + P0 U4 h  l; X2 l  u# w' x( |
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    8 f7 l! s1 t# l6 _) U6 {3 A
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));- M* ?8 N* y2 B- A, x; L8 |: x# G
  553.         Send_Byte(Dst & 0xFF);
    / r5 S# p* n% E) i: [
  554.         byte = Get_Byte();$ j& p2 [: h6 q: E$ {
  555.         CE_High();                                /* disable device */
    ; \# ?- R; ~9 p0 [5 ?. x( ]+ B
  556.         return byte;                        /* return one byte read */& z. [9 V& D. y' Z' F+ M' b
  557. }; v3 g3 [& K' e

  558. 5 s" Q; `' Z: c
  559. /************************************************************************/  r( M8 R& Q8 c; h5 Z
  560. /* PROCEDURE:        Read_Cont                                                                                                */# j+ J! B6 G5 f/ _! ]) S
  561. /*                                                                                                                                                */               
    * X4 S& R' @& Z  W9 Z' F: w
  562. /* This procedure reads multiple addresses of the device and stores                */
    7 J; M: J0 d/ G# {1 Z
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/7 {( Z) }; E' q: {: e
  564. /*                                                                                                                                                */
    . I. q: X; Q, y- ?1 z
  565. /* Input:                                                                                                                                *// Q' r4 [* h% ^7 N
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : u( n4 a+ k% K
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    ; J  }5 k8 u" k8 d' ?# M& Z% V/ u( H
  568. /*                                                                                                                                                */- ~7 M9 H1 F) s9 ?! ?6 a
  569. /* Returns:                                                                                                                                */
    . j9 }* F. N( H+ v+ d4 w7 F
  570. /*                Nothing                                                                                                                        */6 [& y( b+ ~, k
  571. /*                                                                                                                                                */" [2 o$ J/ r' Q
  572. /************************************************************************/) g* j5 j  |: m3 R/ }* E
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes): m% P% n; Q6 s: b& @
  574. {" O1 M* y+ h4 f7 a2 p1 O
  575.         unsigned long i = 0;
    1 O8 B6 D. L! x7 W+ {1 V& P9 n( w
  576.         CE_Low();                                        /* enable device */
    1 P$ {( N/ {1 z! C! ]9 n
  577.         Send_Byte(0x03);                         /* read command */
    - G2 D+ i! Z" m- N( |
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    , T  F: V. l. t: L9 d
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));2 w" V% G* ]) _; \
  580.         Send_Byte(Dst & 0xFF);
    2 j5 b$ F/ J" J9 L/ A1 q: n
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    & A! ~5 e2 g+ h7 J$ M8 m3 p
  582.         {
    4 J3 M9 @8 H* c) s" u
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */9 v/ U5 D1 j4 e5 ^# Y  R0 d
  584.         }
    9 k* U5 K( I7 E! J
  585.         CE_High();                                        /* disable device */9 K& n, q; u; I

  586. ( h/ S( k' M2 ^/ V
  587. }
    ' m$ R/ q. z) A! f4 F4 B9 X+ R

  588. ! [  M& p# k  i! e
  589. /************************************************************************/& X# c2 _, @0 @* \1 C4 R6 [
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */3 G! l, n) ]9 s' N/ E, F% Q
  591. /*                                                                                                                                                */               
    2 [1 N# q! K" k0 m, n( o, N
  592. /* This procedure reads one address of the device.  It will return the         */
    % k2 w. R2 z8 _3 c
  593. /* byte read in variable byte.                                                                                        */5 M6 p# q6 m$ O2 y& q! q9 E
  594. /*                                                                                                                                                */
    , t7 i. h. q, b3 {" E. C6 v2 t
  595. /*                                                                                                                                                */
    - n3 B* T/ f5 ^/ \: q7 v
  596. /*                                                                                                                                                */
    4 ^# \' I9 m" N& ^9 j) U( J0 V
  597. /* Input:                                                                                                                                */
    * X7 `: N" C1 X( M3 `  Y
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */- e3 }+ H3 I, u( k( F- p" v. o
  599. /*                                                                                                                                      */7 A& I) z$ {& T
  600. /*                                                                                                                                                */
    6 \+ q' c1 E, j
  601. /* Returns:                                                                                                                                */
    2 K% b# i$ H1 C0 x/ b: O
  602. /*                byte                                                                                                                        */" E' |. V8 N% r. O) r9 `$ \9 \) d
  603. /*                                                                                                                                                */
    4 W9 G- A8 U( i3 G
  604. /************************************************************************/7 ~3 \0 n$ a+ \
  605. unsigned char HighSpeed_Read(unsigned long Dst)
    . o3 {0 e4 ?( H  x0 X
  606. {
    * H- u/ h3 `; x# Q% l
  607.         unsigned char byte = 0;       
    6 x8 [# n& Y9 g

  608. ) L7 ?6 _; q- J$ B
  609.         CE_Low();                                /* enable device */
    ' T' _! A, ]* ?7 p' \# d) y" E. [
  610.         Send_Byte(0x0B);                 /* read command */' p, {# A* T" @, w( t" g
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    $ V# d1 G( |$ z8 q9 P* d% n6 h5 ]
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    0 C9 {3 J8 G! t6 Z9 U7 ~- v
  613.         Send_Byte(Dst & 0xFF);4 r+ O2 o4 N8 J- p- p
  614.         Send_Byte(0xFF);                /*dummy byte*/7 a+ [, J2 s; W$ n0 m1 V7 X
  615.         byte = Get_Byte();
    ) [5 z7 N* e+ Q2 _/ [. ^
  616.         CE_High();                                /* disable device */
    ; E6 A8 H! p* m, C" w2 t  @# [
  617.         return byte;                        /* return one byte read */: x" F) l) _0 D. m! G; h' t
  618. }
    4 S5 X, p' E$ l  _8 t& T
  619. ) J  p3 K2 g6 p! a  V4 H- F
  620. /************************************************************************/
    * b' Z0 ?8 b' ]+ a8 k
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */) R' s2 _% s% w5 L, f, q
  622. /*                                                                                                                                                */                9 v8 u% y0 E+ n0 M8 L4 G4 V
  623. /* This procedure reads multiple addresses of the device and stores                */
    8 C2 a* E$ p4 l' V
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    ' f( W$ w- v8 Q+ O
  625. /*                                                                                                                                                */
    ( T9 x0 D7 \; x+ G2 g: M9 {
  626. /* Input:                                                                                                                                */% g6 U/ `  \4 @8 u. F% G
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */% M( F, x% J* T0 r+ H% y
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */) ?7 E$ ]5 c) P  t' |* M/ [
  629. /*                                                                                                                                                */
    * L! h5 C# ?4 X, w- x  B
  630. /* Returns:                                                                                                                                */8 n7 ~" L# k6 w( M; B" r$ ^
  631. /*                Nothing                                                                                                                        */. Z  _' M4 l$ n: P! a8 Y
  632. /*                                                                                                                                                */+ \7 p$ T1 o$ O; e' P' n
  633. /************************************************************************/
    2 n+ V" u* `; R. S% N
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    - c4 ]  n  g4 {6 a( C& {
  635. {4 ]) X: w# t0 E0 ^! Q0 s* u5 ]
  636.         unsigned long i = 0;
    ; ]1 z7 [0 m( z! \( l. d; R
  637.         CE_Low();                                        /* enable device */$ B7 v8 ^* r# ^' P% I; _
  638.         Send_Byte(0x0B);                         /* read command */
    ; }! q! v! i6 u/ J9 }* ~
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */& [" _3 q0 J! s
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    % I+ c: o( c* t' S
  641.         Send_Byte(Dst & 0xFF);
    $ ]% y& x  _+ |" @
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    8 c2 R( y1 V' Q
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    * V1 U: m) P/ B! y1 x3 W. y5 @
  644.         {
    * B  K+ h4 Z) b, G; d
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */$ q9 {5 X" l! c/ t
  646.         }% l8 C; d- f4 O- H7 i7 O, M
  647.         CE_High();                                /* disable device */
    3 Z7 _7 H+ \$ [  i# O2 X
  648. }% x0 y0 U6 \1 z8 G9 e
  649.   |. f3 C! \$ e- `  d1 f" ], G
  650. /************************************************************************/* p: T( N4 }; T2 S* R* m0 D
  651. /* PROCEDURE:        Byte_Program                                                                                        */" K2 p+ O( y% B9 I* B7 S  y; b
  652. /*                                                                                                                                                */
    6 d1 A4 j/ ]1 z9 }
  653. /* This procedure programs one address of the device.                                        */0 U( K9 Y3 ?8 j- D
  654. /* Assumption:  Address being programmed is already erased and is NOT        */
    8 g5 o9 Z3 M8 k
  655. /* block protected.                                                                                                                */
    , t/ z( V& l3 f' l1 t" J/ @
  656. /*                                                                                                                                                */# j8 Y  c! P: U$ k4 f) u) J* {4 }
  657. /*                                                                                                                                                */$ ^: Q# u1 U8 t% Q5 S5 m
  658. /*                                                                                                                                                */& t- h9 [5 a8 l$ v! ~0 F' P
  659. /* Input:                                                                                                                                */7 q2 V2 E- Z1 k
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */; _! C$ A& k: C, K6 h4 ^7 X
  661. /*                byte:                byte to be programmed                                                                */! x; }; v2 ~! h! E; P
  662. /*                                                                                                                                      */7 D, j7 l3 T- n' J
  663. /*                                                                                                                                                */1 j3 Q) I  A4 m$ t! |
  664. /* Returns:                                                                                                                                */: d- w7 p: X% B+ s
  665. /*                Nothing                                                                                                                        */
    ) |% i% M7 W- P# ?( i! D
  666. /*                                                                                                                                                */, C9 q- {1 R% Q5 `; V
  667. /************************************************************************/
    % G/ }" ^/ N' {7 d2 n
  668. void Byte_Program(unsigned long Dst, unsigned char byte). G! \$ O& r4 \7 A9 D: E/ N
  669. {" ~9 B, H0 ^% I3 L  Q+ J. P
  670.         CE_Low();                                        /* enable device */
    8 o7 l# \+ ]0 Q7 @0 l1 K3 L
  671.         Send_Byte(0x02);                         /* send Byte Program command */: N3 E4 T2 @# h1 ~7 ]
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */) `7 a/ i1 F% O0 n( H3 G8 p  c$ y
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));1 N3 Q* ]' k# {, {5 P
  674.         Send_Byte(Dst & 0xFF);
    0 S/ |7 w& U: I# C% |
  675.         Send_Byte(byte);                        /* send byte to be programmed */+ i5 k8 a2 `1 {/ g( u1 Z4 l
  676.         CE_High();                                        /* disable device */; N+ Z. P  {" R+ E" y: G7 T7 @
  677. }/ j/ q2 e2 n* [, W

  678. 5 @% Y" C. G5 y
  679. /************************************************************************/
      M" `4 t2 O$ x% T6 E  Q# M( u+ u
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
    1 ?) t3 F% L1 @# @3 M+ `/ j
  681. /*                                                                                                                                                */
    3 Q& W- D! s6 o
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/4 H; V4 e/ q# [& z$ @
  683. /* the device:  1st data byte will be programmed into the initial                 */
    - S' M: S9 Z  X8 l
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 *// y' }4 Z1 l' H+ E9 V
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */
    7 B0 ~# E7 [$ O& o* e
  686. /* is used to to start the AAI process.  It should be followed by                 */
    : ]7 V* \# }, f3 F  F
  687. /* Auto_Add_IncB.                                                                                                                */2 V7 k" D  ?' ^# g1 T
  688. /* Assumption:  Address being programmed is already erased and is NOT        */3 m8 S' |7 X6 t  F* o+ \0 q
  689. /*                                block protected.                                                                                */# I* p( D& ~& N7 G4 x4 `0 s
  690. /*                                                                                                                                                */
    . d  }: M# m( D1 `- O
  691. /*                                                                                                                                                */
    * L+ ?# H9 X8 x8 t% P: h0 I
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    . F/ P/ ?1 o' o9 E% Q: X
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    ; |1 A) J0 g' \( Q( E  t
  694. /*         unless AAI is programming the last address or last address of                */
    6 [5 J% R2 M( {6 W5 c0 c
  695. /*          unprotected block, which automatically exits AAI mode.                                */1 r8 k; J' u9 K; y7 r2 u
  696. /*                                                                                                                                                */! f: |3 D4 R2 R, w- w  O- K6 @
  697. /* Input:                                                                                                                                */! k0 Q3 B4 ?2 m2 D& d
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */& y- X7 w. i5 t( u3 \' ^
  699. /*                byte1:                1st byte to be programmed                                                        */
    ) f% R+ c( s8 c% ]! M
  700. /*      byte1:                2nd byte to be programmed                                                        */- W. K" q. J& _% h' }  ]' s
  701. /*                                                                                                                                                */" U- ^, K0 Q) I" ~2 w9 N
  702. /* Returns:                                                                                                                                */
    9 j6 G" y& w. u- k9 c. u  o
  703. /*                Nothing                                                                                                                        */
    ( k% s1 k( ^. ]- h
  704. /*                                                                                                                                                */  y2 Y7 ~( y) a, E
  705. /************************************************************************/: I; r% y6 s6 Z7 I( i
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    5 I4 u. K* v7 y% `% ]. N+ `
  707. {
    ! ?9 Z" N5 \3 T/ F0 \! n) S9 x+ P0 N
  708.         CE_Low();                                        /* enable device */* `! a6 K2 R) w8 s2 z
  709.         Send_Byte(0xAD);                        /* send AAI command */
      @5 Q* U8 O5 C5 R. R" X
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    8 s2 O/ K+ z! W" \/ B) M; @6 p
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));( R3 |/ e6 p( [
  712.         Send_Byte(Dst & 0xFF);* r( R0 i* n/ z: |+ M
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        2 u) ?. C5 V5 h- g2 d
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */7 }7 F6 r% q$ c: V9 R! n
  715.         CE_High();                                        /* disable device */" `5 O. d# r# U( b+ [
  716. }
    # H% P, w6 A% N" r6 J: r- S

  717. ) W  y: g7 d) K0 B9 b% ]
  718. /************************************************************************/
    . g6 c- {( x' `. p+ T
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */& J9 C3 e8 k6 J2 a# l( V+ p- H5 H
  720. /*                                                                                                                                                */
    # N$ v" l( ]4 c( n( [5 U
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/3 s2 \+ L) z/ W) f" X& A0 ~
  722. /* the device:  1st data byte will be programmed into the initial                 */& m8 V0 E) K: @+ t, J+ y
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */4 P. m* ]' L" Q! r/ A
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */
    ) l) [, P  ^8 b4 `, h2 _, y7 e: q
  725. /* is used after Auto_Address_IncA.                                                                                */
    ! m* y7 v* J! w9 }
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    5 b( o! k0 r8 J- b% K0 q7 b
  727. /*                                block protected.                                                                                */- |0 k0 a* p# g4 f
  728. /*                                                                                                                                                */* j* f. @, x1 U0 q9 g
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */2 s) D& l9 }9 t
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */: I! ?/ x9 ~: F9 l) {$ Q$ ]. X
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */8 L$ ~4 T$ H$ ]: A) G
  732. /*          to exit AAI mode unless AAI is programming the last address or                */
    ( N2 p2 U3 N4 d
  733. /*         last address of unprotected block, which automatically exits                 */, i+ ]7 o* w$ _! d) g% Q$ U- x
  734. /*         AAI mode.                                                                                                                        */' ]$ d$ u3 \! J( k' m. W
  735. /*                                                                                                                                                */- n2 K: N8 w. m, N7 C
  736. /* Input:                                                                                                                                */8 M# F# l8 {, D2 O: R" i3 F5 b
  737. /*                                                                                                                                                */
    " D9 f3 Z8 l3 @7 F' Z$ l' r0 W
  738. /*                byte1:                1st byte to be programmed                                                        */" Y* m% W" f5 U: e
  739. /*                byte2:                2nd byte to be programmed                                                        */
    % W  o* ^) h2 I! B. i
  740. /*                                                                                                                                      */
    . ]! J7 {# O+ G# V: `
  741. /*                                                                                                                                                */
    - h8 }8 b4 |/ C0 |0 p# {* E
  742. /* Returns:                                                                                                                                */
    3 M& M9 L/ H0 S: l/ H' ]. [# D+ x
  743. /*                Nothing                                                                                                                        */
      U, @" ^0 n& i% f2 n0 D2 Y# t
  744. /*                                                                                                                                                */
    5 \0 S% ^9 F( o$ \
  745. /************************************************************************/, @% f' Q; c: {0 t& S& ]2 ~, r
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    5 P/ ~1 S7 `2 O" c
  747. {
    * ~  g, b. L8 p+ L7 D: W! O1 f+ K
  748.         CE_Low();                                        /* enable device */% s, m" l) T1 ~: E6 f. N7 A
  749.         Send_Byte(0xAD);                        /* send AAI command */
    # m6 _4 a( u- Q' t# V
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */* K! L4 Q- Y' X) d
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ) e) x. G( C9 s
  752.         CE_High();                                        /* disable device */+ ^& a9 z; K* |  M5 d9 N
  753. }: c% k( ?6 A! T3 m3 o: ^6 m
  754. ! _1 ?: ~5 m/ M: ^/ f* Q# j
  755. /************************************************************************/& ]5 c: S) }  g; H8 u' G( J
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */3 ]$ E; ~1 H. ?: @; }
  757. /*                                                                                                                                                *// E4 x4 Y5 U( Q5 B+ E
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */- z+ T# E  H' u& L# G
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    7 M1 H9 j0 `  s! @% n
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    5 i. b# @- M) b4 }( }" U  t. A" s
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */
    $ d' ?) [6 v: w7 L
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    ) z1 ~) L% F& N, |4 c
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */
    4 y3 @, T% u- v1 X1 r
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */# G0 u+ q# I' J( R' c# `" D1 O
  765. /* Assumption:  Address being programmed is already erased and is NOT        */
    ) @1 t( A- C$ Q
  766. /*                                block protected.                                                                                */7 k% H' b/ r. W5 O& x7 g' l
  767. /*                                                                                                                                                */3 L7 Y; h  C/ g( e5 k  s3 M
  768. /*                                                                                                                                                */: R; s+ ~$ p# M
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ! g3 H* [6 G# e+ y2 a. U( C
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    & e6 m7 l! r6 ?+ O: C0 ^* e4 E9 M
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    * B! v& q! R7 V) j. Q
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    : s; g/ v  J0 e' ^
  773. /*         last address of unprotected block, which automatically exits                 */
    # _- m- i% W, a
  774. /*         AAI mode.                                                                                                                        */; u3 o  |$ }7 Y* M. L% c* Z0 M! P
  775. /*                                                                                                                                                */
    / h1 p% g  j* O+ K# V
  776. /* Input:                                                                                                                                */
      s6 z9 R. H+ J8 s
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */) K# E7 v, z& }( m
  778. /*                byte1:                1st byte to be programmed                                                        */
    6 g6 l( u& R4 i8 ~
  779. /*      byte1:                2nd byte to be programmed                                                        *// T; |' p" f. f; O- G7 i# w) D: Z
  780. /*                                                                                                                                                */& S+ c1 y% d, h, Z0 y# H6 J
  781. /* Returns:                                                                                                                                */" F5 U1 j2 ]" h" D! h
  782. /*                Nothing                                                                                                                        */
    6 N/ b) X: S/ K) @7 u( l3 t
  783. /*                                                                                                                                                */
      |6 Q- b) T, t& n
  784. /************************************************************************/) q1 `! I( Y5 l5 q
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    7 ?& v" E3 l0 G/ k8 o: Y
  786. {& b, ]7 m; W& L2 l1 y. o1 T6 G& N* d5 s
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        # r# [8 H1 R, M5 l

  788.   m( e: @; ?/ G3 p5 ?
  789.         CE_Low();                                        /* enable device */' z. C( o- `) p6 w
  790.         Send_Byte(0xAD);                        /* send AAI command */
    & X/ b. ]6 L; H  I0 [9 A/ ?
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    - f) X& P, u' ?$ d
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));$ @( X5 v8 I8 p2 C3 w! u  A4 }
  793.         Send_Byte(Dst & 0xFF);; m% l' z- G" e( v
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    3 `. y. P- O. ?( a) m
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    , D( j5 u$ A2 W- l4 d, |
  796.         CE_High();                                        /* disable device */
    8 F+ t  M  V& N5 w9 G6 ?
  797.         $ }" |' b, r- e  p1 M5 D& Q
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    9 u0 J1 [5 H: E# Z* X/ M0 E/ ~

  799. : O3 J4 y. @2 g  @* Z
  800. }
    8 H! \. ^- h- }% I
  801. ' U) W3 y7 j) B, N; T/ @# `+ W( f
  802. /************************************************************************/
    4 q  r. J9 Q/ `) n9 Y
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */! X* A1 O6 z$ R, T$ m
  804. /*                                                                                                                                                */
    & h7 d; k8 d; @
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    ' F6 z; p/ t2 M0 w/ R" l( ?. z
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */# o9 v& Q5 G0 E3 f3 |
  807. /* AAI programmming is completed.  It programs consecutive addresses of */) }9 d: |) \4 C* W9 Y7 ?# W$ h
  808. /* the device.  The 1st data byte will be programmed into the initial   */6 s9 @( H9 x% ^- z2 ]; m9 u
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */5 u+ H) k9 s/ L
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */6 Q3 K9 J  X6 W: x  H
  811. /* used after Auto_Address_IncA.                                                                                */3 _  c. P1 e# U. s0 c9 R  E* t
  812. /* Assumption:  Address being programmed is already erased and is NOT        */3 b6 Q( q8 y8 ?4 q$ H. V2 D2 b4 b
  813. /*                                block protected.                                                                                */; H9 q+ d" G* _" v- b% g
  814. /*                                                                                                                                                */
    * A' x' l# l& I. F) D6 U0 e
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    3 O3 [+ Q: @  z' P
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    8 X4 n( f' J- A+ k) M
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */: V# E$ x8 {  e* j' L0 d) Z
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    ) }* q* z# c8 g4 ^; o. [/ E
  819. /*         last address of unprotected block, which automatically exits                 */
    7 @8 f* V6 B: R5 Q
  820. /*         AAI mode.                                                                                                                        */
    : `; ~. D6 ?1 Y, W! T# _
  821. /*                                                                                                                                                */3 z* w8 Y+ P5 |% _8 V
  822. /* Input:                                                                                                                                */" {9 T* v! \+ r* k) x+ _
  823. /*                                                                                                                                                */8 r7 |, H7 O3 q1 y" s
  824. /*                byte1:                1st byte to be programmed                                                        */
    * s2 l9 L5 H) `5 Y1 h  y- }; k
  825. /*                byte2:                2nd byte to be programmed                                                        */
    ! {7 ]7 ?6 i8 L# J, f
  826. /*                                                                                                                                      */
    - _1 ^1 [& z  |2 n% M7 @
  827. /*                                                                                                                                                */
    ' \6 d9 V1 p3 A9 |7 `
  828. /* Returns:                                                                                                                                */
    $ ?+ s: g( r/ H8 ]2 P
  829. /*                Nothing                                                                                                                        */
    ! r( Q" }- l0 Y! `6 H5 U9 c) r
  830. /*                                                                                                                                                */
    9 ]- O+ V; Q5 ]! O, R+ }
  831. /************************************************************************/
    1 \$ P* K4 E$ M: r* o% K, S
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)& y; S) R8 J" l* b7 h- b7 m2 B
  833. {: r( `$ ?  k8 r6 U
  834.         CE_Low();                                /* enable device */, s- L: @) H9 A0 Q* a- g% J* T
  835.         Send_Byte(0xAD);                /* send AAI command */- x7 L3 d( p, j3 L1 \
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */, r' a% \. o. ]# q% F# L7 Y
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    8 ?" ^2 x8 s- W) v" W  W" B! Q
  838.         CE_High();                                /* disable device */4 @% f; c8 b. M- Q# d( s$ ^

  839.   J) v2 I2 O2 R) k6 j
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
      V; d0 P( M( `5 X: ]: O
  841. ' e6 ^1 e( b4 w3 v
  842.         WRDI();                                 /* Exit AAI before executing DBSY */4 W8 I# h0 m+ [' Z
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    % `$ G8 `% R6 c6 ~. z) D$ b, J
  844. }* \, t' y6 E) _2 O, B6 x" s
  845. " V2 {7 |; H  v$ v+ n* r
  846. /************************************************************************/
    6 B4 y# R+ C1 Y+ y1 V6 i
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    , o8 q6 ]: N7 W" a& i* |. Y9 r- o2 w/ c
  848. /*                                                                                                                                                */
    7 W' \* h) d* N1 N
  849. /* This procedure erases the entire Chip.                                                                */
    * X9 E1 }" N& u7 a9 F
  850. /*                                                                                                                                                */3 ]& J8 w' D1 u: W& G; f7 D
  851. /* Input:                                                                                                                                */
    7 k  k7 H! u5 u' y: r3 f
  852. /*                None                                                                                                                        */
      t8 J& K5 p2 @4 g
  853. /*                                                                                                                                                *// M; x( H2 Y; ^! r4 X% K
  854. /* Returns:                                                                                                                                */) Y7 {  t1 {( {. j7 s( T
  855. /*                Nothing                                                                                                                        */# \& R8 ?  a/ ?$ U8 B
  856. /************************************************************************/
    # s5 y+ F) z0 Y8 V; x# A# h. ?
  857. void Chip_Erase()
    8 Z, f, @4 s  Z" z0 W& F8 ?% k; ^
  858. {                                               
    & b' I$ @) `' u
  859.         CE_Low();                                /* enable device */5 T2 b+ y: u9 h9 S6 ^( _0 }
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    5 S3 }: n* V8 n' i3 r% `
  861.         CE_High();                                /* disable device */
    - ]( |. p, j5 b$ Y" E; L
  862. }# j, w( R+ b3 y
  863. 6 p2 h( j* F+ W# p1 b" @8 c1 @9 `8 j
  864. /************************************************************************/6 v, O' p) g" {) q+ N+ @
  865. /* PROCEDURE: Sector_Erase                                                                                                */+ N6 |$ A6 _0 r# K* p; f& S
  866. /*                                                                                                                                                */
    . {% S  u0 \# h. L
  867. /* This procedure Sector Erases the Chip.                                                                *// ]1 n# H, p  t/ F/ |
  868. /*                                                                                                                                                */2 L  k& b. [+ I/ a( P
  869. /* Input:                                                                                                                                */
    " l* x# n" {2 z6 r! Y% X2 K$ x
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */9 Z3 ~- S. S# Z9 j# P
  871. /*                                                                                                                                                */- N- o3 ^: k9 u7 k
  872. /* Returns:                                                                                                                                */9 ]5 \" v& F$ l2 G9 d/ p
  873. /*                Nothing                                                                                                                        */: ]& R; m3 E7 X. Z& {' D1 ]
  874. /************************************************************************/6 L& |# F' w6 P% v& a
  875. void Sector_Erase(unsigned long Dst)
      h( w0 m$ p: }4 h# V
  876. {
    4 s7 [% K8 E8 d/ k
  877. / a, D) _# o6 ?+ X7 G$ c
  878. $ J. L' p, o2 `% R! P
  879.         CE_Low();                                        /* enable device */
    * o5 F% F% z1 m4 J6 C
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    " ]0 E! F, V0 \. {, x
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */8 H; B# N  e7 D! K+ s9 ^
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));- j9 S6 c) Q% {
  883.         Send_Byte(Dst & 0xFF);
    1 b2 T5 S% w, A- Z2 i* ]
  884.         CE_High();                                        /* disable device */
    ; G( M! H0 I* i, _
  885. }       
    0 Y4 W7 ^+ O% d" o  T; Z

  886. : E- j8 r" {5 L# I
  887. /************************************************************************/: X7 m' Z0 n! v
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */
    ! S8 l6 D* o. @
  889. /*                                                                                                                                                */* A, a$ n* G1 `
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */7 T: y0 u  \4 ^3 K/ B6 _
  891. /*                                                                                                                                                */; e( a9 J& Z5 s1 X( A" z7 _
  892. /* Input:                                                                                                                                */
    0 z  L# t' y- a+ R. x. h
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + b, a6 q4 n  U" {5 [7 @
  894. /*                                                                                                                                                */
    * ]0 j/ V& S3 b/ L
  895. /* Returns:                                                                                                                                */
      h1 z/ _% g$ r
  896. /*                Nothing                                                                                                                        */, P4 h& t4 S" |; J% V( O. A* [
  897. /************************************************************************/% ^& r; r. M/ @* o: z3 A- J8 Z
  898. void Block_Erase_32K(unsigned long Dst)  d  u# d; K4 u/ [& r& i7 Y
  899. {  A, A7 s8 t0 O& g- V* A
  900.         CE_Low();                                        /* enable device */6 J  |9 v: x6 W% ]6 M) T3 [
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    % q6 X: I/ F2 h  n! P
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    # _; X5 q) G9 v4 E) C+ `2 |3 F5 Q
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    , h. o$ ]: U# |/ c" L4 W0 M
  904.         Send_Byte(Dst & 0xFF);/ F" Z6 s. |' Q0 Z+ t) S) r
  905.         CE_High();                                        /* disable device */
    ! c) e0 _, D9 q, Z: \! t
  906. }6 t# N6 m8 ]  ~& Q7 o8 d
  907. + B6 @: B4 e2 h7 D
  908. /************************************************************************/
    : m# j! z( _# f/ F0 l4 N- r
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    * X. H. _% T8 c+ q) w. C; P
  910. /*                                                                                                                                                */
    7 F  {" Q  [( ~8 F& Y9 I
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    & A% ^3 F# v; J( P
  912. /*                                                                                                                                                */
    5 ^# R8 D' ^3 h
  913. /* Input:                                                                                                                                */
    : }. @; U' ^; K8 A
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    ! ?4 Y0 ]1 O: [. j* G
  915. /*                                                                                                                                                */
    1 w( r& G; T( G  V# C. C9 l
  916. /* Returns:                                                                                                                                */+ Z- c% }$ Z, e/ F, o0 b) M8 @
  917. /*                Nothing                                                                                                                        */
    - ?) d3 g2 R+ \, |" F& ?. ]7 n& J7 w5 S
  918. /************************************************************************/- u. l2 ]6 P4 {  m
  919. void Block_Erase_64K(unsigned long Dst)
    ) r: S- {8 O1 H& d6 N
  920. {
    ( j- I4 I$ v! |  ]8 t
  921.         CE_Low();                                        /* enable device */
    $ l" V! G7 y1 _; T- L
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */. E& j1 c' W0 Z8 ~
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    4 t+ P7 C1 Y7 ^4 ]* h
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));. x* `/ V( t1 ]; _
  925.         Send_Byte(Dst & 0xFF);
    . R+ j; `. n: t; I+ z5 _$ k( ~9 o
  926.         CE_High();                                        /* disable device */: ?, g0 Z4 Y: s5 r( ?1 j# [4 ^
  927. }
    , q, y2 t" T, c: Y/ O' Y1 r. J

  928. 6 b7 ^9 a1 B+ e" l5 P
  929. /************************************************************************/' u9 [. s5 c" N0 r0 F0 p
  930. /* PROCEDURE: Wait_Busy                                                                                                        */+ b9 E+ @( ]" V3 s" D0 S2 O
  931. /*                                                                                                                                                */0 L3 d; k7 ~( S2 R( H; t
  932. /* This procedure waits until device is no longer busy (can be used by        */! ~& U* }0 P- D& n
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    5 V$ y# j3 U3 L
  934. /*                                                                                                                                                */3 A) q6 `* s  W* y+ S" x+ b
  935. /* Input:                                                                                                                                */- O3 I( D% H6 u
  936. /*                None                                                                                                                        */2 o* o! F" Y8 [' K. y
  937. /*                                                                                                                                                */2 O2 {5 |- U* ?+ R! v
  938. /* Returns:                                                                                                                                */2 @' e4 t) p9 w% p* r( R9 t
  939. /*                Nothing                                                                                                                        */5 c( v" v/ [* p) W( r( e
  940. /************************************************************************/
      x' ^3 i" ?& u! p# H$ [
  941. void Wait_Busy(). F! |7 `, k2 T) y, B  a
  942. {
    3 Y! V# w8 ^5 Q, [& G& o
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */9 O9 Y1 J* w! b9 Y
  944.                 Read_Status_Register();6 I/ h9 x7 G% V; B; K7 y1 i& ^
  945. }
    2 I0 J0 n  \9 ~7 Z
  946. . c) y, k5 }. t8 C1 f
  947. /************************************************************************/
      [( ~- J9 d; O$ X5 H
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */
    2 M! f) x1 m  X" |; k) ^
  949. /*                                                                                                                                                */, ^& w* e  h- [$ N1 ^3 {( j: Y7 y9 u
  950. /* This procedure waits until device is no longer busy for AAI mode.        */
    0 M, G6 J3 |! ?7 c6 x4 m3 A% ^
  951. /*                                                                                                                                                */* ~) t  j  ~  A  h
  952. /* Input:                                                                                                                                */% s2 W- ?+ w* H# P, D) {
  953. /*                None                                                                                                                        */* y5 X( n5 D2 ^7 c3 }+ F4 F
  954. /*                                                                                                                                                */4 d/ R7 B* S; g! E" I5 U9 ~. c% F
  955. /* Returns:                                                                                                                                */) c/ R$ h# p/ q, U% z7 {
  956. /*                Nothing                                                                                                                        */
    ( ?, S1 f1 D% g# ]6 E( F9 C! T* t
  957. /************************************************************************/
      o3 U0 W* E& |. t/ @  i
  958. void Wait_Busy_AAI(), t+ }. `9 ?5 R
  959. {" A2 ?6 p* V, ?3 }% y( j
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */
    % c: a; Z# f7 h( L
  961.                 Read_Status_Register();
    : @5 D% D( c1 R5 D) H
  962. }
    ! H7 P, x5 D* G( a; |& G% J
  963. % }$ F# ~' H! J0 b+ q& I
  964. /************************************************************************/- }# i  c& r* Z4 z
  965. /* PROCEDURE: WREN_Check                                                                                                */
    3 N# x1 r" W6 A( R) m
  966. /*                                                                                                                                                */
    9 k6 V0 n, g9 s9 m5 x
  967. /* This procedure checks to see if WEL bit set before program/erase.        */" }$ s; Y+ E( M9 m% y4 i/ \
  968. /*                                                                                                                                                */: b' R# B. ?5 R1 L
  969. /* Input:                                                                                                                                */
    , m9 p7 P+ R7 l) M5 ]. D6 j) k! b# ?
  970. /*                None                                                                                                                        */
    0 p+ i* q, f* v! e% g) \3 \
  971. /*                                                                                                                                                */! |2 X7 E" |8 H; s' y: t! U% Z& {$ P
  972. /* Returns:                                                                                                                                */
    ( |! B7 R0 W  u( ~. n. H* J4 Q
  973. /*                Nothing                                                                                                                        */
    % b1 [. {8 q3 v$ Y, |1 I: J+ G2 b
  974. /************************************************************************/
    . e& `1 `& v; C# i
  975. void WREN_Check()
    " V0 I& c$ X/ b. L3 z
  976. {
    7 a% n# @  p0 n" v: b
  977.         unsigned char byte;  y2 k& n# c- V2 S
  978.         byte = Read_Status_Register();        /* read the status register */
    $ x6 Y2 P$ U% Q( i# W/ G" O/ j
  979.         if (byte != 0x02)                /* verify that WEL bit is set */! [* e+ n( C+ E+ N; I
  980.         {
    9 s# o3 c: [3 o2 g8 }2 N# i
  981.                 while(1)
    2 S. p8 }6 J& Q# c9 i
  982.                         /* add source code or statements for this file */8 f4 q( j( l+ \, Z/ S( o
  983.                         /* to compile                                  */
    : p" {1 Y5 j0 Q/ q0 \
  984.                         /* i.e. option: insert a display to view error on LED? */
      J3 p. P- C, Q( C. X8 k5 T" J% d
  985.                  7 V: V& z3 G- [* P3 m- h. c
  986.         }
    8 J5 r0 D/ t' B; d" ]
  987. }
    0 C! v/ ]* p" c, k  O$ \7 |% j

  988. + U. W6 F! W5 ?4 J- @% I
  989. /************************************************************************/
    " [' R8 G( h+ {6 f  P- f
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */
    ( k, b, T! ]1 d# x( s
  991. /*                                                                                                                                                */
    7 O( `3 Y; P  F9 S6 }/ ~$ Q
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */
    / B6 b! l) d# R, `7 O8 L" c0 @
  993. /*                                                                                                                                                */% a: k4 |) K5 D1 T- s0 ^! k# f9 e- x
  994. /* Input:                                                                                                                                *// _* Y1 S" C' m" Y( D* b, i
  995. /*                None                                                                                                                        */
    $ n* `/ C  T3 Z' r6 C
  996. /*                                                                                                                                                */
    ! u) Y" I9 r1 C0 _/ i2 z
  997. /* Returns:                                                                                                                                */. T! i6 j# {, X
  998. /*                Nothing                                                                                                                        */
    - ]: w4 Q/ k& F$ \4 K: }" M$ I
  999. /************************************************************************/! s8 _+ a* G9 v1 g+ B. ^8 P
  1000. void WREN_AAI_Check()2 S/ _7 S: Z* [; f" t5 _
  1001. {% F0 a1 L$ p' P" _4 ^# X3 d
  1002.         unsigned char byte;. u9 }! I/ ?* o% z; n( O/ I! {
  1003.         byte = Read_Status_Register();        /* read the status register */
    8 u, }6 \0 L8 P
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    ( [" m% m. m# u0 U- \4 T
  1005.         {1 B0 k* \. [3 t! d+ U
  1006.                 while(1)               
    " U( c5 n2 x) O* e
  1007.                         /* add source code or statements for this file */0 K  c3 z1 }) P: G) T
  1008.                         /* to compile                                  */! N; p. a) {) y0 P
  1009.                         /* i.e. option: insert a display to view error on LED? */. P, ]: `' X1 ^. E& m+ C1 D
  1010. . D' M% Q4 g/ [& I! Y6 t) [$ R+ O+ p
  1011.         }
    4 Y/ L+ L! E& ~! K, j* R$ q6 ~
  1012. }3 w& x/ D4 v% T2 C/ J/ P0 x

  1013. / s+ o4 M3 Q$ y$ z) k
  1014. /************************************************************************/$ P/ B% P5 B& I. j6 ^$ p
  1015. /* PROCEDURE: Verify                                                                                                        */
    8 f: \7 D9 |: Y2 [2 ^4 G. g
  1016. /*                                                                                                                                                */
    $ t% f: J& U8 ]% }( {7 H- R
  1017. /* This procedure checks to see if the correct byte has be read.                */
    , }7 u- U+ o1 _' `# o7 H
  1018. /*                                                                                                                                                */
    8 X3 i, k9 U; B; r5 [5 R
  1019. /* Input:                                                                                                                                */# j, G) |9 f* @/ `% i
  1020. /*                byte:                byte read                                                                                        */" _% V) S; V" p* R3 c
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    6 N& u) s$ i. c! ^: c& L. \2 E7 h
  1022. /*                                                                                                                                                */
    ; a6 k9 h  P" c" m
  1023. /* Returns:                                                                                                                                */
    1 m2 M) ~% G& D0 z
  1024. /*                Nothing                                                                                                                        */
    : `: t0 k/ m2 n) l
  1025. /************************************************************************/
    ! \% g; A0 ~2 C. p; `  ?
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    5 r4 v  ]! ]# d/ q' a. \  T
  1027. {
    & g3 Z+ L, [" h% V3 t% l6 J
  1028.         if (byte != cor_byte)) c( D" P  p8 t" E( v; e7 I
  1029.         {
    " s: i/ x$ [1 O+ A# ~' o
  1030.                 while(1)
    1 F) q" k$ _& N  n
  1031.                         /* add source code or statement for this file */8 F- f3 Q5 Q: Z* K
  1032.                         /* to compile                                  */% U$ [) s6 ]2 G  \8 [: e6 c$ K
  1033.                         /* i.e. option: insert a display to view error on LED? */# Z  D4 G- d3 G8 J: {# s" Z
  1034.                 . t- y5 {  l' L1 S3 S' W
  1035.         }
    7 |7 i) y, n2 G( o
  1036. }* L9 C* G! @/ C1 E

  1037. 0 }- B$ K$ ?" [2 W

  1038. 3 \6 Z2 N8 {! |
  1039. int main()8 }. Z7 L; A) d) @% M8 M
  1040. {
    7 o8 Q0 ?4 q& t
  1041. : x& Q4 @& s* v
  1042. return 0;
    $ j% _7 C/ k' J
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
, L5 p1 h8 l) p4 D, v) Z- X# G   main()
0 o0 C% M; w- \" ~. l   里面怎么是空的呢?
) r5 f2 B2 c& E. E* f& H3 }! G   发一份给我吧
) Y2 t- M$ R. ~. f8 fmail:luyijun2005@hotmail.com
1 u1 t) }) H5 s$ U咯。。。。
回复

使用道具 举报

 楼主| 发表于 2007-12-11 19:37:35 | 显示全部楼层
本部分就是如此,它提供的是方法,并不是给你拿来编译的.你要main函数能用来干什么? 为什么不看看 Byte_Program...等函数?
回复

使用道具 举报

发表于 2008-1-8 17:42:00 | 显示全部楼层
如获至宝!请问哪里能找到SPI的官方spec(我不是指flash的datasheet)?网上只能找到些片断...管理员是否可以上传spi spec至本站?
回复

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。
1 f1 d  x4 K" C8 a/ @& |9 t, q4 q, |9 a$ |; X6 c( t* c' w
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
! p. X9 T& i; M" k, uEC的代码在哪跑,你看DS的说明,每个EC都不同的。7 H: y9 {" n. i8 c$ q
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?
  q- X% L) j% I" H% Y& r上面几个问题是你没看任何东西而白问。
' M. I- A& |. u0 P4 l
0 C2 y( @) {1 E' t/ a" u0 I' F至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
0 T- F4 f0 U) i. U& V4 q
5 x+ e( Y1 d7 R( ]关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!6 e& `5 K2 d/ L* `4 e: I  w' X
& b+ c+ I; F5 O$ T
关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”: X. t& I1 J, k* ?/ V

/ d. o& E) f$ w5 ~" A2 Y$ F$ J* o关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...' a$ Q1 h6 o1 H

- p6 ^: V# P: M. h- A不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样. H( }% O: |& S! C
似乎要把SPI能support 到最大,这EC chip应该有好卖点  Z$ W! O) t4 k4 u
BIOS功能要不要强大,也就决定了SPI Flach的大小
+ p1 j6 l4 Z; v- a我是这么想的~让OEM去决定要挂多大!
# C' l! P* q5 ^% R" O- n如果我司有BIOS工程师就好了~哈2 B2 G' T& ]" b8 P
WPCE775应该算很新的东西,来看它支持到多大?
, j' D$ D' t, ~  M( S+ j  }' {3 U9 H* ]6 `8 l' r3 H3 v8 g
另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte% l7 W( p7 J/ L4 n& r0 F0 F
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.
4 Q/ _$ k  t4 \
# ~! t4 q  q" }4 g% b: D- ^这份driver收下~希望以后有用到- w9 u; |) A1 n' F) m
谢谢bini大大, B4 h' G$ x6 y$ g2 q7 x( p
  G3 F  ^; ^, X* d* v
很新很新的新手,如有错误请指正 (准备看第二家的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()
+ J+ J$ b$ x8 n% V6 x{& P0 i: R5 d0 ]
        unsigned char temp = 0;7 x& Z$ t/ ~2 K( r  o
        CE_Low();
0 t# ]* I: K( b4 F$ T    while (temp == 0x00)        /* waste time until not busy */1 }" j2 `+ B5 [
                temp = SO;0 z$ d! B/ s' E# e. P- F
        CE_High();
8 z% L8 g, p+ _}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
$ A9 Q% G: m: h5 {; F{
: V: |" Y/ }+ }( @        
% y6 b* I4 B. o        unsigned char i = 0;* R5 ^4 V7 T& \% A# ], Q, u
        for (i = 0; i < 8; i++)
' g& k% k/ N2 ^% H' y        {. j2 s& F! h: U% E, N+ G# f7 |
                & i* [1 k/ l; ~$ a! |, f
                if ((out & 0x80) == 0x80)        /* check if MSB is high */) S$ K: T" S% D+ N" M, E3 T
                        SI = 1;7 Z- Q0 k# E8 X$ ~2 [
                else$ y/ N& Y! x: k+ ?. `+ i
                        SI = 0;                                /* if not, set to low */8 P6 v4 X0 t5 V  x+ F
问              SCK = 1;                                /* toggle clock high */  G2 J4 @0 }7 H. O/ \3 a1 o
   题            out = (out << 1);                /* shift 1 place for next bit */
- ]0 y" Q; F& A* Y                SCK = 0;                                /* toggle clock low *// i8 ^& @* C- Z$ i* j
        }
0 g5 W% \+ o  O& }3 ^6 N2 }0 j}+ ?0 L# H4 w0 G; g4 K; s9 A
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-20 10:17 , Processed in 0.030113 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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