找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 55222|回复: 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/ J! `. e/ h9 n9 i- [, l2 e% J/ L

  2. - V# W' k1 v$ T( B% R$ p
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory2 M7 u2 F' \4 N' e! [2 _7 u
  4. 9 A8 Y% W( f+ P
  5. November 4th, 2005, Rev. 1.02 V9 p* h& U9 ^
  6. 3 o9 m  c* G& q
  7. ABOUT THE SOFTWARE
    % X) q- h% P4 b
  8. This application note provides software driver examples for SST25VF080B,
    1 s( h7 p$ M9 H. a+ g0 x8 n
  9. Serial Flash. Extensive comments are included in each routine to describe
    1 Z1 Z' }/ J5 S3 X9 d' z
  10. the function of each routine.  The interface coding uses polling method
    & U& L5 W  V% W8 Z
  11. rather than the SPI protocol to interface with these serial devices.  The2 r5 P: w3 `8 A" S! E
  12. functions are differentiated below in terms of the communication protocols
    : t9 R- f) L8 g$ D- k  h
  13. (uses Mode 0) and specific device operation instructions. This code has been ! H$ [. T: S4 @0 a/ i
  14. designed to compile using the Keil compiler.1 h* b# i( A9 Y; B$ L: g
  15.   q5 E4 z  K& p3 y# c+ \% h
  16. $ p! ^' X4 h, p: H. r; z+ J
  17. ABOUT THE SST25VF080B8 K; a% ?' \; g" P

  18. 2 F( p) Y* e% P* D: H; r
  19. Companion product datasheets for the SST25VF080B should be reviewed in + a- S( I5 H$ i0 Z" `( p4 K4 H
  20. conjunction with this application note for a complete understanding
    # f2 |, |. J6 l& z/ J+ a
  21. of the device.
    ! D' `9 m2 R. k4 `) U4 r
  22. / h& _" u# g( x1 ^3 k$ h7 c

  23. & A0 B  z5 C/ P$ N" |  u
  24. Device Communication Protocol(pinout related) functions:
    ( G2 U( @- Z) q3 L

  25. 5 d; t2 b- a: I) y# a9 S0 m0 V
  26. Functions                                    Function
    $ ?  p5 |- p" G3 J! x( X, e
  27. ------------------------------------------------------------------2 n5 u' b4 G9 Q9 X& E+ Y
  28. init                                        Initializes clock to set up mode 0.- r/ i( Z% L+ _( `- N
  29. Send_Byte                                Sends one byte using SI pin to send and 2 g5 Y$ d/ e1 R' ^% i7 x
  30.                                                 shift out 1-bit per clock rising edge5 @; F0 F) m% k! B" ]
  31. Get_Byte                                Receives one byte using SO pin to receive and shift * X* a4 P# U. s
  32.                                                 in 1-bit per clock falling edge$ P; K( k/ }6 T
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming7 B( G6 B. ?1 M
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high
    ; S- i. q) Q* @9 k0 m; H7 {
  35. CE_Low                                        Clears Chip Enable of the serial flash to low
    * O- Y; Y2 R# D9 L1 b
  36. Hold_Low                                Clears Hold pin to make serial flash hold
    # ]2 Q% z4 C$ f+ {8 F6 x
  37. Unhold                                        Unholds the serial flash) l: X; ~4 i, i/ c7 p5 U
  38. WP_Low                                        Clears WP pin to make serial flash write protected! m# j8 @/ n% T0 O
  39. UnWP                                        Disables write protection pin( i# U& B% h! m3 r3 @
  40. ) [( c( e: C. F. d2 }
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    ' ^' J( O9 `0 P$ r0 c
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your! B2 n# v, X, i  y* L
  43. software which should reflect your hardware interfaced.          
    8 h" U& i/ d: b( K# k: D

  44. : B: x* E9 {+ A7 m
  45. 9 p. W4 Y# u$ j% p
  46. Device Operation Instruction functions:
    8 K+ g  e  W7 ^* S

  47. 0 }5 e. [+ t& [$ S+ W$ @
  48. Functions                                    Function) e" M- B2 o9 Z7 {+ F+ P
  49. ------------------------------------------------------------------
    4 R- W- F! K7 v# z7 }3 T5 v% m
  50. Read_Status_Register        Reads the status register of the serial flash: N: n9 I2 q, u" D
  51. EWSR                                        Enables the Write Status Register
    - B% A- ?; `! r% E0 P. i& N' |) Q5 r
  52. WRSR                                        Performs a write to the status register/ G: U/ o# T# I" K; n4 x% y9 W
  53. WREN                                        Write enables the serial flash( r/ g7 `4 U/ N8 n) s' Z/ p& y: J
  54. WRDI                                        Write disables the serial flash
    3 K5 |4 L3 e6 Q. C2 P% x
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming2 j, `1 a" P* ]( K
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming: w: a: Y2 \* @; p( h
  57. Read_ID                                        Reads the manufacturer ID and device ID
    - W, P* f# l8 E2 @7 m! {+ o+ j
  58. Jedec_ID_Read                        Reads the Jedec ID6 Q6 P/ Q. h1 C4 _1 j
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)+ R! H- k0 w6 Q* T
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)* x% U0 `# }* }6 ^% Q
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)1 Q! c- C" s( ?, b6 X, O* V9 U
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    7 A$ X6 Z7 G0 ~* n+ H+ U0 T4 B  ]7 `
  63. Byte_Program                        Program one byte to the serial flash
    9 `( c8 C* E  s$ p
  64. Auto_Add_IncA                        Initial Auto Address Increment process5 p8 V- B) P& n# R+ Y8 O" M4 U# b
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation
    * _; _# Y! n# [4 j
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY! S; F! A; x: A- e9 h) |
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
    $ M' C( T+ v% h( n& I- J! E- ?
  68. Chip_Erase                                Erases entire serial flash8 `+ O; m6 G! j5 f9 e
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash
    4 Y* O  x5 b3 y
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    # D& I; [* T" n+ `( x
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    % {0 |* x2 W/ u* f
  72. Wait_Busy                                Polls status register until busy bit is low
    ' Y' f% I, o4 W
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming3 o6 M5 \4 h/ d5 y: n# k
  74. WREN_Check                                Checks to see if WEL is set8 x* U4 ^! _, H" n/ ^
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set9 h" G+ f) S& a- d# C; a9 l( |- T6 v

  76. 4 P4 M8 h3 }$ a* V' L. V/ W) \
  77. 1 o: V+ b9 R# N1 q' S) L! E3 x

  78. 5 {  H: T. T% M6 a. E0 h8 P3 x5 x! w
  79.                                                                      
    ' K5 z0 {3 H1 @1 T) {
  80. "C" LANGUAGE DRIVERS
    9 y7 L( H' r! g, A6 D& P* @1 {7 ^
  81. # b) [/ r" {) J- p' [' o
  82. /********************************************************************/* @* D; G# T& L9 O; A" P
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */2 y( m# U4 S- _4 G2 J8 [$ }- o
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */- k6 H0 K+ J, X" e1 [2 k
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */
    " I/ u$ r% u0 I" D5 t
  86. /*                                                                  */: i, v3 d. o/ X5 m
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    4 z2 W2 Y, d( x& O
  88. /*                                                                  */
    7 P8 x; _) [2 @4 z" B
  89. /*                                                                                                                                        */4 F8 t/ M, J7 c- J1 I
  90. /********************************************************************/
    * [& b/ }' E. _3 T3 @' G- i
  91.   N7 u1 \' y% b8 ]: M, k+ p
  92. #include <stdio.h>
    / M& W  M( x: z" v/ P
  93. #include <stdlib.h>" d/ N. H, T. g* R# A
  94. 3 A' t- P7 O* p5 C  {
  95. /* Function Prototypes */# N- y9 A9 v0 n. g, p: w: ^

  96.   I* d. V. k5 t4 g0 a, C
  97. void init();( d3 _3 W7 p- H2 ~  F
  98. void Send_Byte(unsigned char out);
    % X2 ]/ x  D( `# C0 k( U
  99. unsigned char Get_Byte();  W2 n: m, v6 j! L
  100. void Poll_SO();
    ) A4 E9 f+ {3 X5 u  S% K9 ?0 A
  101. void CE_High();3 F: A5 Z  A/ N. g( M! C
  102. void CE_Low();
    . w: E& N8 q2 X4 ^7 b$ [
  103. void Hold_Low();' }- w) t8 `/ \  D& f
  104. void Unhold();
    : p) d# l4 D6 m3 w
  105. void WP_Low();
    + w$ A7 C0 x$ P& G/ g9 c1 Y! y/ O
  106. void UnWP();* B& L  M1 H" Z- b
  107. unsigned char Read_Status_Register();
    & R; k7 E' K/ c8 {. C9 ^: @2 m
  108. void EWSR();
    9 @; c9 l) x1 D( {+ Y
  109. void WRSR(byte);
    4 }& B. O' S; z; h
  110. void WREN();
    # J4 \( a. f( [7 X8 }
  111. void WRDI();  X7 v8 Z& [- ?' I' A( c: Y
  112. void EBSY();: Q3 W4 q3 S! m- r/ E( i
  113. void DBSY();
    7 l4 b% z  H. W' a* `
  114. unsigned char Read_ID(ID_addr);+ h& E3 K0 U9 A" k
  115. unsigned long Jedec_ID_Read();
    9 p* k& i! g7 S5 G: T: j8 G
  116. unsigned char Read(unsigned long Dst);% g! r1 b$ e1 g9 o# D3 \" i
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);
    2 L" H1 E4 U- z
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    ' d" P8 h  S6 \4 Y" c/ s% `" z
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);+ l- U8 A0 W& A6 K3 ~5 q
  120. void Byte_Program(unsigned long Dst, unsigned char byte);4 |3 J6 |: O! C
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);! C6 `' |7 s3 {% g- ~+ u
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
    & K% J& S* r9 P6 J+ v
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    3 B' v9 i9 I* b+ v- n9 @
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);0 t; O5 {6 Q+ M$ M9 G' S" s4 D! w
  125. void Chip_Erase();
    3 H" `9 W. g% D* o; q: ]) g5 d
  126. void Sector_Erase(unsigned long Dst);. [  M+ J7 _5 ~
  127. void Block_Erase_32K(unsigned long Dst);
    9 Y" \7 o5 k1 O3 P
  128. void Block_Erase_64K(unsigned long Dst);
      s# Z: U2 `( a+ t
  129. void Wait_Busy();
    , W; k3 e  z1 j: E& `
  130. void Wait_Busy_AAI();
    8 _+ Z9 A! ?& L3 V
  131. void WREN_Check();3 X3 J  }  ^( J
  132. void WREN_AAI_Check();! p- K: U+ k+ N4 c7 w0 }+ h  T
  133. % L' {6 Y- s0 _/ w, |
  134. void Verify(unsigned char byte, unsigned char cor_byte);% F: s$ Q. I4 W
  135. 1 P1 f8 ^! l. k1 b2 Y
  136. unsigned char idata upper_128[128];                /* global array to store read data */5 X& i/ K5 H' H$ ?
  137.                                                                                 /* to upper RAM area from 80H - FFH */
    # @0 T  N3 _3 p, W# A! r# F6 B
  138. 7 o/ \% h: @; [
  139. /************************************************************************/
    6 u& F9 W4 p9 \  V2 y6 k4 J
  140. /* PROCEDURE: init                                                                                                                */
    0 C5 U8 t  ]6 y; w. a% I0 t- v) X2 U4 N
  141. /*                                                                                                                                                */5 l3 `3 ?4 Q) C3 g- `
  142. /* This procedure initializes the SCK to low. Must be called prior to         */% [1 Y6 e- G5 d% d
  143. /* setting up mode 0.                                                                                                        */
    - T$ B7 a5 [/ C
  144. /*                                                                                                                                                */. Q: O1 P' [2 w5 z2 o" z  \
  145. /* Input:                                                                                                                                */
    ' U2 ~( e+ V( r
  146. /*                None                                                                                                                        */
    3 H3 q4 `8 {, J$ Z- J/ y0 C! r
  147. /*                                                                                                                                                */
    , N3 D+ S: Z! ^$ R, F! f
  148. /* Output:                                                                                                                                */
    2 A  r+ l7 }: u
  149. /*                SCK                                                                                                                                */
    5 u' k4 b7 V8 K" A
  150. /************************************************************************/# ?  b9 c6 G' {/ h. }8 @! J" ~
  151. void init()& ]$ n6 ~/ A; f' H3 y$ [9 }
  152. {
    ( L! f0 q* C1 x
  153.         SCK = 0;        /* set clock to low initial state */% J: g/ x) L) }; {/ K3 D' \1 U
  154. }
    : a3 K( l* l2 v7 @

  155. 4 j" S% k5 Q: M6 B2 q) q% L8 G9 J# f
  156. /************************************************************************/
    4 x9 V; j4 c1 o0 _
  157. /* PROCEDURE: Send_Byte                                                                                                        */8 L& r& ~4 G) B; c8 s6 d
  158. /*                                                                                                                                                */
    2 C+ y. ~3 t, L$ [  U1 @9 V
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */
    # m' Q1 g$ U: y6 z& p7 F' y% t. a
  160. /* edge on the the SI pin(LSB 1st).                                                                                */. e4 m+ V+ R2 x, U9 b$ {: D# c. c. w. B0 M
  161. /*                                                                                                                                                */
    & N3 f8 a4 a: g" O- ^
  162. /* Input:                                                                                                                                */
    " m9 n0 D/ g; r9 f
  163. /*                out                                                                                                                                */
    # @0 {) u0 K2 e" |: ^% \: ~* r
  164. /*                                                                                                                                                */" e8 `+ a1 b2 N' P
  165. /* Output:                                                                                                                                */! w- x, I" K; ?2 K
  166. /*                SI                                                                                                                                */$ V! n% A8 @$ W& i7 |& @8 y3 N1 \
  167. /************************************************************************/
    + T$ q4 y0 A& |! g- k! H
  168. void Send_Byte(unsigned char out)- Z1 t* @/ f) W$ ~
  169. {
    / M" K, B! X. k! L: Z+ Z
  170.         ' \' Q1 h& V$ j" m1 q
  171.         unsigned char i = 0;( ?$ d' q8 g! i6 V9 F; H$ B1 w
  172.         for (i = 0; i < 8; i++)
    ) U. s( p& a) z9 v* Z
  173.         {
    / P; e6 K6 S& O/ d& O( y2 I
  174.                 ' w9 @; B8 ]8 u& w9 q2 m+ Y' b
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */% j% r& A( g9 m
  176.                         SI = 1;  Y% |7 A; F, `/ `! x
  177.                 else
    # E. \0 u; s2 `) d5 n. J" G. P( V
  178.                         SI = 0;                                /* if not, set to low */7 T( D6 ^% g' @' X9 r/ |; E
  179.                 SCK = 1;                                /* toggle clock high */* x5 s+ {% N. l8 I
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    / h+ h* A3 b' I" C
  181.                 SCK = 0;                                /* toggle clock low */
    & ]" p8 M' O+ G( j! A
  182.         }* D; o2 a* b7 c- d/ f. m
  183. }
    * S7 [% V% C& Z& _" Y+ p8 j' `
  184. ' B* C# m% G% |: R8 e
  185. /************************************************************************/% d2 `1 z; L: H
  186. /* PROCEDURE: Get_Byte                                                                                                        */2 e3 }+ e8 N3 ~) w" o2 m1 U
  187. /*                                                                                                                                                */5 [( r4 W* \$ ], R. A6 ^! t7 `
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */  G8 R& j/ ~" a0 F) g* k
  189. /* edge on the SO pin(LSB 1st).                                                                                        */  y" |/ a1 _, _3 c, Q
  190. /*                                                                                                                                                */8 B/ a, {! E% g& C/ t7 `! k
  191. /* Input:                                                                                                                                */
    5 Z1 V& P2 B9 v; N( X1 g$ F
  192. /*                SO                                                                                                                                */( r5 ]; @( h% n/ O5 i
  193. /*                                                                                                                                                */( i- U* t) U: |" u- V" o% |( V
  194. /* Output:                                                                                                                                */
    . C- Z2 Q8 t! N, G9 I7 O: R: ~: V
  195. /*                None                                                                                                                        */
    7 k: }# l2 L- q
  196. /************************************************************************// N& j8 Q# H" p
  197. unsigned char Get_Byte(), N. r& {" J: i& M' X
  198. {
    5 s+ C( \6 p, P
  199.         unsigned char i = 0, in = 0, temp = 0;/ n4 l; H) M) ^$ z; u2 {
  200.         for (i = 0; i < 8; i++)2 U7 J5 b+ u" d, F* i6 B
  201.         {
    : |- x9 O# q4 J/ ~7 }$ o' R: l
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */
    / z4 d) J4 c1 G9 o
  203.                 temp = SO;                        /* save input */. N0 J) {0 K+ s, Z3 X+ E4 Z
  204.                 SCK = 1;                        /* toggle clock high */& [9 P% @6 R9 N1 i" D
  205.                 if (temp == 1)                        /* check to see if bit is high */
    ' V! ?3 y( o5 F9 j- A5 }% }
  206.                         in = in | 0x01;                /* if high, make bit high */! h. [! d* C' e1 T+ l9 r
  207. 2 X1 P# u, _9 |6 u8 P
  208.                 SCK = 0;                        /* toggle clock low */
    3 i8 p0 }8 f# ~% T% e# s3 W
  209. % c" {9 l; L: O' k& |# m  P
  210.         }* b! c3 I1 h0 U0 [. |
  211.         return in;
    - d# }  `2 V) U- g) ]
  212. }
    % e. ?: ]) y' d* ]" `

  213. / S! ]( S$ W# H: T) p& o
  214. /************************************************************************/' h' ~. V1 Q" N0 ^6 I! P
  215. /* PROCEDURE: Poll_SO                                                                                                        */2 e$ G1 `( u7 V  }, J0 s1 f
  216. /*                                                                                                                                                */" d7 v" U6 K# m
  217. /* This procedure polls for the SO line during AAI programming                  */
    ; k- ^- T' z/ Y1 F$ N% W  m  R" y% Y
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/. S1 h* S: r" N0 }" H, W* f
  219. /* is completed                                                                                                                        */
    1 }# D! a! u' k# P( x0 _
  220. /*                                                                                                                                                */
    * {8 |: ]: k# P4 B5 P# W2 w
  221. /* Input:                                                                                                                                */
    ' }3 C+ S/ f+ Z5 s# a
  222. /*                SO                                                                                                                                */
    / i4 d! W2 O. b
  223. /*                                                                                                                                                */8 o( H! K+ h% k# L
  224. /* Output:                                                                                                                                */) N0 N& |% f& X! j2 Z! L8 }
  225. /*                None                                                                                                                        */
    : H. J! X% p* R; s3 a
  226. /************************************************************************/8 Z  `# u& k/ ]) p, G/ u( A! ]
  227. void Poll_SO()' M; K& n0 t6 f$ F
  228. {
    0 e; U6 ~) E+ D1 A6 s" i
  229.         unsigned char temp = 0;
    % E, M- E$ _0 c! t
  230.         CE_Low();
    * ?; E& S2 a& d$ g
  231.     while (temp == 0x00)        /* waste time until not busy */
      p7 j  j; g! l" S& }0 x& C" x
  232.                 temp = SO;$ N. o( s2 x4 K' h, R' }8 h
  233.         CE_High();! c- D5 Z- @+ a0 R
  234. }# D% P* n. T/ v: s. [+ Z' E% R) v) i
  235. % s3 k$ `) n; N$ D% Q) K* f
  236. /************************************************************************/
    3 k* z4 V0 L# i- f
  237. /* PROCEDURE: CE_High                                                                                                        */
    9 k! m6 _. t' l# T
  238. /*                                                                                                                                                */1 [3 V; C: F  _& [
  239. /* This procedure set CE = High.                                                                                */8 s6 K! v- j6 s" T" n) {0 ^
  240. /*                                                                                                                                                */* q3 S6 ?, ?4 _$ Y5 S
  241. /* Input:                                                                                                                                */
    ' H& D4 ?  k2 R  c5 U
  242. /*                None                                                                                                                        */& v8 ~) Q# G& _& l: M! W4 V
  243. /*                                                                                                                                                */
    ( h$ {# O. z  V) b. q+ b  ~+ J
  244. /* Output:                                                                                                                                */
    8 Y5 R* }" c+ n1 ?: R
  245. /*                CE                                                                                                                                */# |' `2 x" W5 a( A* h- ?
  246. /*                                                                                                                                                */
    ; R# B: I0 `# l6 i6 X
  247. /************************************************************************/; s3 `  p8 G1 D2 y$ W
  248. void CE_High() % [! h2 F, Y# [
  249. {
    0 J8 I, K' c2 }  B8 r; c
  250.         CE = 1;                                /* set CE high */
    . C" G, E% Z# y) T6 o
  251. }$ [1 n% w7 O3 y1 j' J/ W! n

  252. ; ^; Q1 B- I, X' m2 X! [
  253. /************************************************************************/5 v& e+ T2 z8 ~8 p1 u# Y
  254. /* PROCEDURE: CE_Low                                                                                                        */
    ' f; x+ j* r5 @1 K0 k
  255. /*                                                                                                                                                */
    4 v4 ~) i, ]/ k
  256. /* This procedure drives the CE of the device to low.                                          */
    / g  r5 \: U! u& x
  257. /*                                                                                                                                                */$ J5 A8 W4 j& `2 O+ V
  258. /* Input:                                                                                                                                */
      u* E) X3 ?( c' @
  259. /*                None                                                                                                                        */5 G% v; o+ y, u  V5 i
  260. /*                                                                                                                                                */- N# `7 S* L7 A$ m9 A, s
  261. /* Output:                                                                                                                                */4 k/ ~9 R, K% g1 x: m' d
  262. /*                CE                                                                                                                                */' q- L$ z: Z% V$ b
  263. /*                                                                                                                                                *// f  k( }) W" H7 K; Z
  264. /************************************************************************/
    0 B3 |! A& i7 k: ]/ V
  265. void CE_Low()
    9 ]( R) T; P2 Z3 r! B( ^/ v
  266. {        7 c7 D- i4 b& f5 ?$ M( w/ u7 M
  267.         CE = 0;                                /* clear CE low */
    : i, w! V7 u; {5 n4 Q
  268. }
    ( C) i4 p( @+ K8 T( X
  269. 9 l6 s+ ~+ i% f7 |8 `
  270. /************************************************************************/7 O2 q# U3 I3 |% D
  271. /* PROCEDURE: Hold()                                                                                                        */
    ) c- i' j. |1 K8 d/ N# B: r
  272. /*                                                                                                                                                */
    " i# T% P, O  ^6 r% b0 u' k
  273. /* This procedure clears the Hold pin to low.                                                        */
    0 V  D: ]0 ]4 C. Y" b
  274. /*                                                                                                                                                */6 a4 Z+ q9 I) Z/ E" w
  275. /* Input:                                                                                                                                */4 ?9 o. f  M2 X# m: Y- y9 B
  276. /*                None                                                                                                                        */) q8 O/ s: n/ A2 U3 W
  277. /*                                                                                                                                                */
    $ J" d# ]: n  u* o- `) B
  278. /* Output:                                                                                                                                */
    5 f, V7 y) n* t$ V8 }1 q/ H8 I
  279. /*                Hold                                                                                                                        */4 z. k9 `1 d( d9 j4 P  g% A" g
  280. /************************************************************************/0 ~% L3 q8 o+ T  O# @
  281. void Hold_Low()
    2 r# R3 }* M$ o2 n& S; n$ J
  282. {7 d; p! Z; ?5 n
  283.         Hold = 0;                        /* clear Hold pin */
    - G' b7 u1 p; J% U
  284. }' p9 g% {' h6 X8 N, C9 T0 j
  285. $ L( \( x, x5 V3 M% L9 ?% B
  286. /************************************************************************/
    & l% Y; G$ t( Q4 H
  287. /* PROCEDURE: Unhold()                                                                                                        */. n& Y* e1 b, a, q/ U
  288. /*                                                                                                                                                */. N* r' C, m6 ]* k& p( s' Y% F3 P
  289. /* This procedure sets the Hold pin to high.                                                        */
    2 B/ c, M+ ^' R+ }' b* r) B6 C
  290. /*                                                                                                                                                */* q& v% R1 v/ q$ ?  t! {, s8 L9 b
  291. /* Input:                                                                                                                                */
    * m% p; j1 K) |
  292. /*                None                                                                                                                        */
    . j+ K1 h: |% a' V. ]
  293. /*                                                                                                                                                */
    ( W7 P: l% L8 l3 }- {
  294. /* Output:                                                                                                                                */
    1 p/ l- E6 z; \% Z" w+ D. B
  295. /*                Hold                                                                                                                        */
    " ]) W; p0 F9 n
  296. /************************************************************************/
    9 m# Y( I( ~* _; W% l' L. L' }. j* [
  297. void Unhold(). B+ c& F1 _3 i5 `" [: j
  298. {7 g- p: {3 a5 F; i
  299.         Hold = 1;                        /* set Hold pin */' r0 O8 Q6 q5 B$ G% C* \0 y8 Q* N3 t
  300. }
    0 g; U$ E- L8 h5 y# R
  301. - t9 [6 h# a9 i  ~7 w
  302. /************************************************************************/# [. T" m- u, ~
  303. /* PROCEDURE: WP()                                                                                                                */
    ) Y$ h. q/ s- |* A
  304. /*                                                                                                                                                */- Y/ i2 z2 {/ W7 I7 t; r2 d+ W
  305. /* This procedure clears the WP pin to low.                                                                */
      W  O, x  J* g; s" q! Y1 y% }
  306. /*                                                                                                                                                */
    % A. h7 c/ }2 X* s
  307. /* Input:                                                                                                                                */
    / f0 O6 y) j& e  h0 X: u; z
  308. /*                None                                                                                                                        */$ c4 q' \4 r, O) Y& }# J/ W8 P
  309. /*                                                                                                                                                */
    * f/ k; D+ t1 i6 @+ `6 \2 T, h
  310. /* Output:                                                                                                                                */, k9 C4 D3 Q' c: F# z
  311. /*                WP                                                                                                                                */
    : P9 m/ i$ i7 g6 D( u
  312. /************************************************************************/
    7 F  ~" Y$ m2 }, A" U' M7 G8 X
  313. void WP_Low()8 d  A- S2 \1 i9 x' A& v5 {
  314. {
    # R% V6 O4 i9 ]% P' b
  315.         WP = 0;                                /* clear WP pin */$ P! s; }" F* w1 U" v, X% G
  316. }
    2 `6 K. O% D  f0 T
  317. ; T* V& g7 ^, ]* ?6 t: W/ ^  s' c
  318. /************************************************************************/
    . r3 c, t8 S+ J+ }6 _4 r
  319. /* PROCEDURE: UnWP()                                                                                                        */
    ' z  P& E) s( p& x" q$ ]( w1 Z
  320. /*                                                                                                                                                */' J  U5 R6 j7 @. ~& N* g+ t: U. C
  321. /* This procedure sets the WP pin to high.                                                                */4 y9 x* A) B/ q! ?! w7 y+ g0 N, W
  322. /*                                                                                                                                                */  O" c% I+ n9 B- ~' x3 p. m
  323. /* Input:                                                                                                                                */
    / W6 ?- K) @$ W' _) h
  324. /*                None                                                                                                                        */: _( i5 ~- u0 y$ n" K9 q5 P7 |. ^( y
  325. /*                                                                                                                                                */
    7 d2 P' U5 E2 q3 }! _, z7 S
  326. /* Output:                                                                                                                                */6 ^% ]( _: }  ^
  327. /*                WP                                                                                                                                */
    ' n+ b/ E8 c* F5 p# C3 V+ C
  328. /************************************************************************/6 K7 J6 Y, ~% @* \5 H* N; G7 V
  329. void UnWP()
    : R# [, \# w& K4 x7 ^1 J, y4 ^
  330. {
    8 C1 |) F" s4 ^2 y
  331.         WP = 1;                                /* set WP pin */
    2 _& v5 [  ^4 P, C( I* M
  332. }
    4 v% r) A- a6 l4 S) q" {% e* T5 M

  333. 1 i5 X6 r/ I; X( I2 v: r! p
  334. /************************************************************************/
    ; E; ^0 n5 n$ `. t; Q7 z1 x
  335. /* PROCEDURE: Read_Status_Register                                                                                */: O6 s8 {. C, L: ]9 ^  N4 V  {' P
  336. /*                                                                                                                                                */8 i  u$ J' b% @) H/ X" t# o
  337. /* This procedure read the status register and returns the byte.                */
    & z% Q1 Z( U, _; n# B! n4 y
  338. /*                                                                                                                                                */
    0 b9 r/ H7 n  Z1 b. F
  339. /* Input:                                                                                                                                */
    4 D0 F" I: O; F7 x
  340. /*                None                                                                                                                        */1 _' ?0 h/ [0 d8 Y
  341. /*                                                                                                                                                */
    : s* v+ q( q+ D; g; o) b( q! s8 [
  342. /* Returns:                                                                                                                                */. s" r% v* d) p9 Z- n
  343. /*                byte                                                                                                                        */
    , K$ D; ~; O& V1 |0 P
  344. /************************************************************************/
    $ r4 x# U5 [% v8 i* [7 Q
  345. unsigned char Read_Status_Register()
    8 m3 B2 F5 H: v( o6 i
  346. {: W/ T" V  n! `& W5 d& _) q
  347.         unsigned char byte = 0;
    5 s% r( C" s8 j* {! K( i' J
  348.         CE_Low();                                /* enable device */7 G, B! @6 S; A% J, ?- g
  349.         Send_Byte(0x05);                /* send RDSR command */' ]9 q9 [$ W( v
  350.         byte = Get_Byte();                /* receive byte */
    / l: g4 ~/ G0 e7 O% _$ @
  351.         CE_High();                                /* disable device */$ O  R9 O& M' c9 {
  352.         return byte;
    + L. V" }, _- c8 ^2 w5 G  \$ X
  353. }
    $ ^: X$ }* `; q9 b
  354. 3 N+ a# ]6 H% Q- p( u
  355. /************************************************************************/
    . x/ `& ^3 k* U' D# ]$ c9 S
  356. /* PROCEDURE: EWSR                                                                                                                */8 }( L- [7 s" z8 ]. f' v' u$ x
  357. /*                                                                                                                                                */4 U7 _+ ]3 Q' C: a0 t
  358. /* This procedure Enables Write Status Register.                                                  */$ f3 d% O; P" Y5 k9 j( r; k
  359. /*                                                                                                                                                */( S6 k+ A1 ]( t) D9 D
  360. /* Input:                                                                                                                                */
    0 V! p( |3 M0 u0 r6 f1 C7 J+ Y8 N; p& H1 c
  361. /*                None                                                                                                                        */, t9 ^4 q" U: Z  `
  362. /*                                                                                                                                                */
    2 h- {, e! ^4 Y4 R+ [- y) B+ _. X! G
  363. /* Returns:                                                                                                                                */
    6 U. B0 y  m) R" B
  364. /*                Nothing                                                                                                                        */! O9 ]0 N# m" N1 N2 T
  365. /************************************************************************/
    7 s2 d. A) n  x3 b: P5 w
  366. void EWSR()  D9 W  W/ c& n  r! q( K- ]
  367. {- P, @4 m* D/ a+ F. e
  368.         CE_Low();                                /* enable device */& I0 b, b: d" D1 \" d
  369.         Send_Byte(0x50);                /* enable writing to the status register */3 s- p" z) Y; S, G- j
  370.         CE_High();                                /* disable device */
    ) z# I/ V4 ?( N  E8 D6 w0 {( R
  371. }
    + t0 b% V. g( }. N
  372. 6 K2 \" O; b! r( h2 }0 s7 S- Y
  373. /************************************************************************/
    4 x1 Q' |) q7 M- q
  374. /* PROCEDURE: WRSR                                                                                                                */; V7 h( C6 V/ C; x& s
  375. /*                                                                                                                                                */- r" S) r+ G) x" t) f6 E& r
  376. /* This procedure writes a byte to the Status Register.                                        */7 U' z7 F8 W, b2 f9 r1 x
  377. /*                                                                                                                                                */5 q5 l9 e+ N0 o3 b5 [9 a3 A
  378. /* Input:                                                                                                                                */3 z& `/ S, e$ F5 Z
  379. /*                byte                                                                                                                        */: `! ~+ H+ b  `- |% P* R. z
  380. /*                                                                                                                                                */
    ' M; B  i* y3 n! G  W
  381. /* Returns:                                                                                                                                */  m+ _2 P) P) i2 ]) R/ u
  382. /*                Nothing                                                                                                                        */" b) o+ n8 r& X4 z9 q6 j
  383. /************************************************************************/
    $ L% F; _/ g6 }+ k
  384. void WRSR(byte)
    2 k4 Z$ l5 m5 B, N& k  w7 f& ^
  385. {
    $ h' k& j4 T' e+ G
  386.         CE_Low();                                /* enable device *// A" ?& {+ i2 o9 k1 L  f
  387.         Send_Byte(0x01);                /* select write to status register */
    ' c$ D% g: k4 z% W$ ~; u
  388.         Send_Byte(byte);                /* data that will change the status of BPx
    ! _+ |( a& q8 d0 C
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */
    2 X$ W7 k  x) |' ]1 x
  390.         CE_High();                                /* disable the device */( L& s% K; I9 a8 t# T
  391. }. z# l% q& }" v

  392. " |. I8 f6 T3 c8 H+ W1 \1 _
  393. /************************************************************************/
    & m& U. |/ I* K9 L
  394. /* PROCEDURE: WREN                                                                                                                */8 m1 M( x0 i  r. g  `9 e2 ]
  395. /*                                                                                                                                                */* x0 D4 a6 m: p- j9 {
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */) d5 q8 E' V) O+ }
  397. /* to Enables Write Status Register.                                                                        */
    8 U% b3 x9 g3 Y
  398. /*                                                                                                                                                */
    & {2 r) K& w1 \
  399. /* Input:                                                                                                                                */
    $ W3 H* F, J3 Z& y6 k! Z
  400. /*                None                                                                                                                        */
    " l/ a5 j. z( X" a5 j$ E
  401. /*                                                                                                                                                */
    % D  I* g1 J" B5 D; C- B
  402. /* Returns:                                                                                                                                */
    % o' a! r( R$ u# q% T: p- X* d
  403. /*                Nothing                                                                                                                        */
    ' t9 m" t! c5 v2 K# y
  404. /************************************************************************/# O6 Y8 n3 @& R- I
  405. void WREN()" R6 c% G/ o8 Q0 c
  406. {
    3 S4 C5 z1 R$ O1 \
  407.         CE_Low();                                /* enable device */
    9 h- e* M0 ^- ~3 x9 r" ^9 l2 O
  408.         Send_Byte(0x06);                /* send WREN command */. S! Z" u& ]$ M
  409.         CE_High();                                /* disable device */
    9 r* c5 A, ~" F
  410. }
    ! z# W$ V' X0 W: e
  411. $ e% S% Z# s, z' u
  412. /************************************************************************/
    ! D- i8 j6 T. k) w0 J  e5 i
  413. /* PROCEDURE: WRDI                                                                                                                */1 h" H* f& k8 K
  414. /*                                                                                                                                                */
    : C* D7 q4 B" d5 o
  415. /* This procedure disables the Write Enable Latch.                                                */* w. p  W0 _# [1 l
  416. /*                                                                                                                                                */; n9 ~9 C! f  j3 y. X
  417. /* Input:                                                                                                                                */, Q% O4 T; n" _# y- L/ X
  418. /*                None                                                                                                                        */
    8 }% i% Y8 Y6 s: ^
  419. /*                                                                                                                                                */
    % f. m$ T( G, O  A
  420. /* Returns:                                                                                                                                */
    & o8 @- a; G: u: I' i
  421. /*                Nothing                                                                                                                        */
    . h: }$ Y- N9 G
  422. /************************************************************************/
    9 [* m2 ]5 U' n# K) J# R* m6 h  s! K: N
  423. void WRDI()
    9 T* l. ]: R0 a9 b3 L7 S
  424. {
    : E1 f/ a# U2 u5 |
  425.         CE_Low();                                /* enable device */
    / D. W! S- I0 G- K4 z* s  x
  426.         Send_Byte(0x04);                /* send WRDI command */
    ! r  v+ a  ]1 U$ z. p; ]
  427.         CE_High();                                /* disable device */
    9 L$ B. y- s9 O
  428. }9 P0 z; }, k1 ]! S# b
  429. & h* d0 R7 z& z8 Z- i
  430. /************************************************************************/
    * G( I- p: V: K3 z1 v2 z4 l! E* ]
  431. /* PROCEDURE: EBSY                                                                                                                */* j$ f. I* n2 m; V) [
  432. /*                                                                                                                                                */) d7 l5 c8 y. Y
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */( M6 }5 q& T; ]$ W% e$ O
  434. /* programming.                                                                                                                        */: P/ w0 L( I% m  e! p
  435. /*                                                                                                                                                */
    0 v. A$ U! }/ ~- O1 h7 V! Q9 m0 a2 ]! a  r
  436. /* Input:                                                                                                                                */
    ! n1 B& q4 p7 u2 a2 j  I! e0 N
  437. /*                None                                                                                                                        */
    1 L$ |' g) l0 Q9 G  i1 h( q; m! n
  438. /*                                                                                                                                                */
    ( U0 A1 c' q: ~  e% D
  439. /* Returns:                                                                                                                                */
    6 T" D. Y$ u) c+ Z, u: t. Z
  440. /*                Nothing                                                                                                                        */) o" n9 c7 w% j* J+ m  R' t8 `
  441. /************************************************************************/
    ! ?4 h5 O1 Z4 i6 x  Y  k8 E# E8 U$ N
  442. void EBSY()
    $ j; m; ^- x$ x) ~: Q! f
  443. {/ R/ U( r3 {" }
  444.         CE_Low();                                /* enable device */
    # ]& ^6 A. w1 U# C) J4 `
  445.         Send_Byte(0x70);                /* send EBSY command */
    9 P* o1 }4 I: G
  446.         CE_High();                                /* disable device */
    5 B! r' F) \6 P+ K/ t
  447. }
    % g0 d& P, U) U
  448. 8 X: D+ q1 R  ]6 i' x9 [" h
  449. /************************************************************************/) e# o) }6 O8 w: x5 w7 F
  450. /* PROCEDURE: DBSY                                                                                                                */
    0 G" E; `' ?$ F7 p8 n/ Y
  451. /*                                                                                                                                                */
    & B) v9 o; X! U9 X
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */$ s6 r* ?2 a) d" y% l- P
  453. /* programming.                                                                                                                        */* ~  W# t) A- ?- v
  454. /*                                                                                                                                                */; l( y/ O* `# M& W
  455. /* Input:                                                                                                                                */
      f* p2 j+ b3 c* s$ C
  456. /*                None                                                                                                                        */
    ) y, L! C4 ~8 o  i9 ^0 s
  457. /*                                                                                                                                                */0 C) v4 H6 s  g5 Y8 c" N
  458. /* Returns:                                                                                                                                */
    ' k. e) M, y! H3 y( y% _
  459. /*                Nothing                                                                                                                        */
    : I+ q2 f' b( _5 R/ }, I
  460. /************************************************************************/( y, r4 v# M! v8 z' c/ k2 S7 Z( b
  461. void DBSY()$ e7 k8 \: ?2 r
  462. {' h& J- u' A& ]
  463.         CE_Low();                                /* enable device */7 k8 E; _8 u' ?, ~5 W
  464.         Send_Byte(0x80);                /* send DBSY command */8 W6 B3 _; U( [8 J; v% W
  465.         CE_High();                                /* disable device */1 u4 Q. [) c( s! T; ^
  466. }
    : v1 C- `- g9 w; ]$ Y; c

  467. : Q! V4 L% x8 X1 ]
  468. /************************************************************************/9 P$ p* S  M7 S, U: y" F
  469. /* PROCEDURE: Read_ID                                                                                                        */8 o/ i% w' U. v) C# ~+ ]. F( `# z
  470. /*                                                                                                                                                */+ L1 b" N6 F7 r$ J; }9 d5 b
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */1 }- Y  o7 l) W( W1 K
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */
    + u2 A" |; b1 t3 ^- n2 D) }
  473. /* It is up to the user to give the last byte ID_addr to determine      */1 ?: ~9 ?/ \$ z
  474. /* whether the device outputs manufacturer's ID first, or device ID         */9 y! Z; r/ V# v, V' |! ]
  475. /* first.  Please see the product datasheet for details.  Returns ID in */
    ' u6 e% d* Z$ w, \' c9 z
  476. /* variable byte.                                                                                                                */
    # h& X7 M- t7 e$ Z( U0 b8 K
  477. /*                                                                                                                                                */+ L5 w0 \1 O& s( c
  478. /* Input:                                                                                                                                */. d  ]8 K7 f) W- M5 E5 n
  479. /*                ID_addr                                                                                                                        */
    + T8 d0 q# n* i% z; C. R, S' ^, L
  480. /*                                                                                                                                                */7 w% s7 s8 m$ |/ n
  481. /* Returns:                                                                                                                                */. L+ O: j: H, `4 U9 h
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */9 z& M4 W2 F/ b
  483. /*                                                                                                                                                */, k- Z% t  A. T
  484. /************************************************************************/
      f' R" B( w* A8 M; u
  485. unsigned char Read_ID(ID_addr)# O( X; X; r* a+ L( j
  486. {
      w- w; r$ L" }. T
  487.         unsigned char byte;# H6 x$ V- y7 T  q3 z
  488.         CE_Low();                                /* enable device */9 {  |  b3 E8 j/ ^# O! a0 x9 u, l
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */" x7 \) T3 m+ u9 H1 V, r& K
  490.     Send_Byte(0x00);                /* send address */
    % D( J2 p" E: U, y# c- {
  491.         Send_Byte(0x00);                /* send address */4 U* v1 w# h0 e$ w& s3 f
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */6 m, y7 ^: @& _- L
  493.         byte = Get_Byte();                /* receive byte */; f: ^" \$ {5 J* r3 j8 A- o
  494.         CE_High();                                /* disable device */0 v4 W& c( o) Q0 D5 @6 I
  495.         return byte;. k0 A2 S( T$ ~
  496. }
    6 {, t  l/ ]! q& }. [

  497. 3 q6 W7 W# t* w  _
  498. /************************************************************************/
    5 ^7 S$ n0 @( c& H, b5 p  s
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */5 p: ~" h3 _9 p& D+ m
  500. /*                                                                                                                                                */0 k+ Q$ v: c/ i# F" D
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */! G4 r5 W" V, [; u( I
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    $ y6 M- U6 X% R, J- s7 p7 Y' ~5 H* y, p& l
  503. /* Please see the product datasheet for details.                                                  */
    2 o& B# ~! ]) j+ q1 R' S1 x8 w
  504. /*                                                                                                                                                */
    : I: j8 x* r/ L  w4 m
  505. /* Input:                                                                                                                                */
    ( G" ]4 p  I% D# j7 V; o6 ~
  506. /*                None                                                                                                                        */
    ) x; w9 D& s- M! X9 o6 |
  507. /*                                                                                                                                                */
    - g; z$ ~5 ]; R4 U5 Y3 A% T
  508. /* Returns:                                                                                                                                */! a( j* Y* s. o; Z
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */9 k* z; f& v& |. z
  510. /*                 and Device ID (8Eh)                                                                                        */
    0 ]' B3 i' r4 \& g8 O: q7 [
  511. /*                                                                                                                                                */
    0 j, u- E) J: ~' F! {9 L7 {# C
  512. /************************************************************************/4 _5 s9 v9 o( w8 `4 _
  513. unsigned long Jedec_ID_Read() & X5 l" C9 ?/ p0 ~  P4 p( {
  514. {
    + e! j3 w3 g9 E
  515.         unsigned long temp;# ~  W8 F( E9 W
  516.        
    6 L3 o; S" F. x! `. M+ n& @
  517.         temp = 0;
    9 Q7 s% M5 l# Q0 G
  518. # G4 P9 p  I8 g( |8 [
  519.         CE_Low();                                        /* enable device */6 y! ]9 X* }2 o: q) I5 x
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    # y$ D8 Q: \" ^' Z' h3 h+ x3 Z
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */6 t. c  b: k, J0 W
  522.         temp = (temp | Get_Byte()) << 8;        " Y  f) I: m# P" {( J! e8 F* W- v
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */2 s8 d$ X8 T9 y$ ~
  524.         CE_High();                                                        /* disable device */
      l& ]# x# [5 C6 V/ a: A7 d" {' n
  525. - f8 V" e3 ]6 O+ b
  526.         return temp;8 W0 s+ g+ P2 }
  527. }
    # n, R! g" ?7 ~9 ]" l
  528. 7 X& l5 _1 ?9 ^6 `- t1 L
  529. /************************************************************************/
    - c/ A0 j8 R3 D( I$ k6 F6 ?
  530. /* PROCEDURE:        Read                                                                                                        */" C% ]0 j! Y2 w$ j% f
  531. /*                                                                                                                                                */               
    + k3 y6 M) N$ L9 g) T+ z
  532. /* This procedure reads one address of the device.  It will return the         */3 P& u1 e0 ~: x
  533. /* byte read in variable byte.                                                                                        */" G& J5 T/ m" R
  534. /*                                                                                                                                                */- p7 q( x0 f' j$ i
  535. /*                                                                                                                                                */+ \% ?# E, n' Z6 A6 j2 s. [6 U. v
  536. /*                                                                                                                                                */
    1 Z7 b- }6 T& g+ o7 V
  537. /* Input:                                                                                                                                */
    " L! ], R( |: p- q0 u2 S
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    2 R2 o1 R' a) F; g& j# }
  539. /*                                                                                                                                      */
    # m8 F9 F& @0 p" J' l6 [
  540. /*                                                                                                                                                */
    $ l, C4 c" S- a3 U% T) g; C
  541. /* Returns:                                                                                                                                */4 f- |( }/ L( W1 Q
  542. /*                byte                                                                                                                        */
    3 g  S# U" \4 b, Q, @  N
  543. /*                                                                                                                                                */
    & V& U4 H8 k9 l, r
  544. /************************************************************************/
    4 J9 ]8 W5 ?4 ]" h
  545. unsigned char Read(unsigned long Dst)
    + ?/ U, M4 r, b# t8 n7 c* m
  546. {
    1 K; H' D5 s2 |3 X" _6 t- u6 X' m
  547.         unsigned char byte = 0;        , Q2 M: f/ i& ]: {

  548. 6 o* Q4 ^4 E- a7 B% k
  549.         CE_Low();                                /* enable device */& j/ u; N% [1 L$ ~
  550.         Send_Byte(0x03);                 /* read command */
    1 _8 Q6 |* K' \8 Q9 A, V
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */$ o$ o1 k0 Y3 U; P) d7 \5 |0 {
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));% N0 r: ]& m+ ]. K3 ?3 q
  553.         Send_Byte(Dst & 0xFF);* `. w( K. U7 d/ z+ y! X
  554.         byte = Get_Byte();
    - r6 z# {& F& ~( w* h% g5 D
  555.         CE_High();                                /* disable device */
    ( B# `  M7 S7 T5 f$ [$ W
  556.         return byte;                        /* return one byte read */: a5 G, M* T3 w( C$ _% O; x
  557. }
    0 Q' l' y. I4 w& o; O

  558. * t* F+ p7 w; A# Y
  559. /************************************************************************/3 B0 t& g- i. u( T# w
  560. /* PROCEDURE:        Read_Cont                                                                                                */" M+ Y4 l' E$ `& o
  561. /*                                                                                                                                                */                % L7 q9 s2 X8 |* F, @6 q4 q
  562. /* This procedure reads multiple addresses of the device and stores                */  e; d$ c! G4 y! Q# M/ z* l
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    0 Z  K) ]5 X' U0 f3 T' f
  564. /*                                                                                                                                                */
    ; d1 L: ~9 U; }& e! g! e
  565. /* Input:                                                                                                                                */) b! w( o9 m/ r1 g% B
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    4 T6 _+ Z0 v: w. e
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */, ~! \# g& z, |5 z5 f$ Z4 O/ q
  568. /*                                                                                                                                                */6 @- f7 w7 ?8 o: I, ^4 H9 u
  569. /* Returns:                                                                                                                                */: ?/ @/ f& g% b
  570. /*                Nothing                                                                                                                        */
    " v8 _/ G8 x2 {2 q, ~
  571. /*                                                                                                                                                */
    2 W% n2 x4 r( V' t* v: ]3 G
  572. /************************************************************************/
    ; i9 l7 ~4 [  S! j( n
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    7 g( S! Q- B, n0 I+ o
  574. {, B: u5 N' }, C1 f  A6 b
  575.         unsigned long i = 0;  Q' n6 x% ]$ O9 {
  576.         CE_Low();                                        /* enable device */
    4 ?- w" X0 J. C- x4 H7 p
  577.         Send_Byte(0x03);                         /* read command */
    4 S8 I# O: ?0 p+ ?/ E# C
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    6 c( k3 ]; \/ N
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ' B4 [( o% i6 u; {( {9 s8 B, p* ?
  580.         Send_Byte(Dst & 0xFF);
    . ]: F: o8 }; F
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    ; Y% G3 q  X: \% l9 }" s
  582.         {
    ! h7 W# ?" u6 {/ s/ G
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    $ K2 d, v$ K/ q/ ]$ W7 u) i
  584.         }
    $ h+ C  }% I; u' ]
  585.         CE_High();                                        /* disable device */
    6 }! a5 Q" a0 d9 i  X/ i* ]6 ~0 w
  586. # y1 y2 p8 v$ P8 ]* r8 ^
  587. }
    5 }- b  b+ G8 e) N# w9 |
  588. 5 ?$ p2 m/ p7 _- n8 T
  589. /************************************************************************/
    7 \" z6 p% l4 L: c  E2 h$ W- R
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */
    0 L  w7 n1 \% D) }0 w
  591. /*                                                                                                                                                */               
    8 M' m* B2 L; ]7 J8 h
  592. /* This procedure reads one address of the device.  It will return the         */
    * x& X8 _' Y, o- ?) \& @; \" y! E1 k* i
  593. /* byte read in variable byte.                                                                                        */
    4 o$ \+ g( }' ^# ~
  594. /*                                                                                                                                                */8 w0 K) x6 f7 |9 ^! ?# w% P0 ~  w/ J
  595. /*                                                                                                                                                */7 O# [+ t' A- o; D5 u
  596. /*                                                                                                                                                */
    / ^( m0 ^6 s! P" K
  597. /* Input:                                                                                                                                */4 A( R8 i" {  f+ j" u1 _
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */$ S7 P  q! d, n% y+ N
  599. /*                                                                                                                                      */
    7 m0 p1 N* ~  d  L4 x
  600. /*                                                                                                                                                */1 _( \. K- S2 P9 |. d
  601. /* Returns:                                                                                                                                */
    6 w" N% a1 m1 y0 k  u+ N; N) v
  602. /*                byte                                                                                                                        */
    % W. T& D9 `. a- \/ F
  603. /*                                                                                                                                                */8 Z0 a4 R- k. O$ G4 L
  604. /************************************************************************/
    9 ?. |1 ]% U* p2 f0 C% ^+ _6 N
  605. unsigned char HighSpeed_Read(unsigned long Dst) 8 `# _; y, B# c, G3 a+ r
  606. {
    7 @+ E+ S1 O2 l6 q6 N; \, E
  607.         unsigned char byte = 0;       
    ( c8 [) k5 u2 S: A7 n3 E% i
  608. 6 {2 x8 g7 b4 l9 l
  609.         CE_Low();                                /* enable device */
    ( y( I: Y( h  N% ~& Z, n
  610.         Send_Byte(0x0B);                 /* read command */
    " x0 Y( B- T5 b- J" j; H: m! M
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */# d+ w8 g3 h9 z; D3 a4 r
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    * L" ~* b. ?) I  c' ]0 Q0 y6 j' o
  613.         Send_Byte(Dst & 0xFF);: G: H) S4 b: y: B" l
  614.         Send_Byte(0xFF);                /*dummy byte*/
    0 z7 P' ?# L3 U: q/ L0 l8 b
  615.         byte = Get_Byte();
    - V6 A; W: O/ S
  616.         CE_High();                                /* disable device */. V' D1 L% q& I5 `' n- v. f
  617.         return byte;                        /* return one byte read */# z) ^! _" q8 S' W4 E
  618. }
    6 N9 l6 F; u$ {- t- F0 u" j7 S

  619. * W) @# r! B/ z
  620. /************************************************************************/
    # K- H3 I. c9 x+ v% a* ?8 W& N
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */  W' y% A0 g9 z# [0 B2 [. |& x  N
  622. /*                                                                                                                                                */               
    2 W) o) r+ D  Y# s- R0 ?/ v
  623. /* This procedure reads multiple addresses of the device and stores                */
    . _' I& v  t. G7 G2 r1 v: a
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
    $ T3 |; @0 C2 O0 k2 N
  625. /*                                                                                                                                                */8 G: b: Q3 n0 P1 b5 N* V, |& C" `" v
  626. /* Input:                                                                                                                                */* L9 G& H1 Y$ ]. C) p/ J
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & F/ c: J; f/ D1 _& E; f
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */
    7 x! \/ E% w0 ?& U: P$ r
  629. /*                                                                                                                                                */
    ' G+ k( l9 H% t6 [/ A3 t
  630. /* Returns:                                                                                                                                */7 j  B" [1 i( r' ^
  631. /*                Nothing                                                                                                                        */
    : d, E  m1 l2 _% q' R+ X. _2 m, X
  632. /*                                                                                                                                                */
    ! J% }' }* m% d
  633. /************************************************************************/
    / V9 @! D" h$ g' g8 g0 P
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
    * s8 T8 O; F! M- H
  635. {2 a$ o2 D# \" E! B
  636.         unsigned long i = 0;# e5 R6 `! i$ p( y
  637.         CE_Low();                                        /* enable device */* S6 R. `( q% n8 t$ H' I
  638.         Send_Byte(0x0B);                         /* read command */  X9 }2 \) p0 H  V: K% F# }4 `" D7 \
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */& h) D" m# }1 Z3 W* q
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));. N0 j: [4 E" Z& v- C, \
  641.         Send_Byte(Dst & 0xFF);0 G2 X' b5 a: t, l+ ?. e
  642.         Send_Byte(0xFF);                        /*dummy byte*/
      n5 r# N% `: |3 G5 C" ~: A$ S
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */% W4 g8 R, Z, c
  644.         {3 g7 r' E' b9 f2 J2 E9 ?5 u' ?
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */" |- J- g* i# u, ]
  646.         }6 `3 b5 b8 N4 J8 X
  647.         CE_High();                                /* disable device */0 w3 z) f! E4 X8 V5 {' Q. _
  648. }
    / q& G, s5 ~* ]6 j: g6 \6 ~" k
  649. / t  R, o  v& w1 X, J$ w
  650. /************************************************************************/: Q! ?$ w- w$ p$ L) J: K
  651. /* PROCEDURE:        Byte_Program                                                                                        */7 @5 l% m! }) |/ j, q6 {" `* s
  652. /*                                                                                                                                                */8 {" e8 N# z; j7 M' l+ A
  653. /* This procedure programs one address of the device.                                        */
    ' r/ }! C+ I% m, E* ]
  654. /* Assumption:  Address being programmed is already erased and is NOT        */( e# ~: S) x5 s8 Q- Y& P# u
  655. /* block protected.                                                                                                                */& J* W$ K; u& x9 Z5 \: g5 C4 n; ~
  656. /*                                                                                                                                                */6 V2 h: \6 C. L1 x  F
  657. /*                                                                                                                                                */9 q7 \. O% N! p& S& L: n* G1 v
  658. /*                                                                                                                                                */
    ( `7 `- l# |: w. L" _# |
  659. /* Input:                                                                                                                                */( Y% L3 v9 _2 m! y7 a
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    # h7 T7 ]0 Y0 G6 a) K4 M' H5 i9 t
  661. /*                byte:                byte to be programmed                                                                */
    8 J; ?/ Z; ~; D5 `: L6 c4 u6 L
  662. /*                                                                                                                                      */0 l. J2 {0 M: K" f
  663. /*                                                                                                                                                */
    , P1 L9 k3 d) g! r0 O
  664. /* Returns:                                                                                                                                */
    - x- v" J8 {% Y0 r& R  E7 X; P
  665. /*                Nothing                                                                                                                        */
    6 G* k9 L, n' d# X5 z6 T
  666. /*                                                                                                                                                */% R- Q- f; O, u. E/ ^
  667. /************************************************************************/
    , H+ f( S( M! o( t3 i5 F
  668. void Byte_Program(unsigned long Dst, unsigned char byte)
    3 m/ X5 u* N7 f8 O& |7 V
  669. {: j( f6 ?  r7 M' n+ v
  670.         CE_Low();                                        /* enable device */
    7 b: f3 u9 L* B) h1 D5 g
  671.         Send_Byte(0x02);                         /* send Byte Program command */
      S7 E$ m5 R6 ~2 a7 c* @9 [3 h" g
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    % Y) c' f* z& G9 S5 |5 v
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));8 E; ]; I9 p: P5 i. u5 G
  674.         Send_Byte(Dst & 0xFF);
    : ^  y  Z+ ]  I) K
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    3 }+ \" D+ R+ ^
  676.         CE_High();                                        /* disable device */
    # h. k* }7 O& s0 h2 }! Q
  677. }' C: r' C- G% N
  678. 5 t& N4 f3 ?2 M4 V0 X" l
  679. /************************************************************************/
    , B. ?3 a8 C5 R. q; R
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */% F4 O! g! o6 L% h( E
  681. /*                                                                                                                                                */
    ! O+ ?: j! Y& M4 x3 x, r
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/" b" b$ k# R' |
  683. /* the device:  1st data byte will be programmed into the initial                 */
    / J% f1 }! _; s6 [- L2 e
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    ' y; Y1 O# I# g$ i9 O
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */# c* H( C/ a, ~
  686. /* is used to to start the AAI process.  It should be followed by                 */
    7 j- P3 V! D% r& J6 J* B/ l6 @; a
  687. /* Auto_Add_IncB.                                                                                                                */0 ^  y8 T$ F7 L* V# a( c# M8 ]( q/ Z
  688. /* Assumption:  Address being programmed is already erased and is NOT        */, X8 B$ N7 S* F+ H
  689. /*                                block protected.                                                                                *// q4 m! ]* _( H, Y! n
  690. /*                                                                                                                                                */7 O' @% M1 h: [7 v9 N1 }3 N, G
  691. /*                                                                                                                                                */9 p" x3 m' ]- g* `( u0 l3 _/ i
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    9 W# i  ]( R, ?% s- V
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 *// v7 E5 Z9 z# @0 O, n- _
  694. /*         unless AAI is programming the last address or last address of                */+ v2 }0 L! y) N3 u& N
  695. /*          unprotected block, which automatically exits AAI mode.                                *// d9 S% C& Q; }) s* C
  696. /*                                                                                                                                                */2 O3 x* B5 n5 Q9 B' h7 i
  697. /* Input:                                                                                                                                */% \4 k1 _" A4 {. ~$ o6 S
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    . I: x( S7 o7 k$ A; z# C. Y
  699. /*                byte1:                1st byte to be programmed                                                        */* i. V' d5 I% X- }3 x9 m2 c
  700. /*      byte1:                2nd byte to be programmed                                                        */
    9 M2 U1 \; x' h1 c" g
  701. /*                                                                                                                                                */; ^( ^- z, h' w
  702. /* Returns:                                                                                                                                */
    ( b4 Q7 d' n9 Z/ ^% M1 A
  703. /*                Nothing                                                                                                                        */
    1 |- a; g' M7 n* E# [
  704. /*                                                                                                                                                */
      m+ b7 k# @( Y& s, q4 {- B
  705. /************************************************************************/
    ) J# T7 \; r' f! E* \1 o' [" A
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    & z' y3 w5 X7 P2 s
  707. {; G1 {$ j5 p* `. a7 J7 b
  708.         CE_Low();                                        /* enable device */
    ; E2 r- z% s9 y* ?, R6 ^" h
  709.         Send_Byte(0xAD);                        /* send AAI command */
    * o  {6 }. B1 q3 a: E: g
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    . W+ q3 X8 B5 `& l) J4 A
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));; p9 q* c  L2 g" a; [
  712.         Send_Byte(Dst & 0xFF);
    7 D( ^3 `0 R" f5 B7 a
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */       
    & {+ Q$ k" ^5 z) F6 W+ O
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */, J+ `  q+ y- V7 z
  715.         CE_High();                                        /* disable device *// b  U2 ^  S: Q5 X9 s
  716. }
    - d; u) D2 ~1 {# B- @1 @% A

  717. 8 q8 b  N/ g$ g2 i3 J/ s- D
  718. /************************************************************************/, m; W/ b7 s+ ^1 T# V
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    8 X2 A) V, N( W+ K
  720. /*                                                                                                                                                */
      @* T) h8 m1 o3 O
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/* J  t: q9 D' n6 A1 U7 g8 K
  722. /* the device:  1st data byte will be programmed into the initial                 */# u7 w) V; V* U% _! b
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    & A1 V5 O6 i% Y7 ~6 J. m  ^" x
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */- p9 Q' H- {% U# R' {4 V( }7 f
  725. /* is used after Auto_Address_IncA.                                                                                */
    8 [6 \' @/ f9 ~$ H
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    7 I) Z% S; w$ V0 _) ]1 H" \- T
  727. /*                                block protected.                                                                                */
    5 F- ~  |* a8 j- ^- r! u+ j( H# `5 _
  728. /*                                                                                                                                                */
    * H6 x% v# y# _# w0 @' @
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */" H* W/ }9 ]- ~9 ]
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */( L" j2 |8 N/ n* P
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */6 D" T' |8 l/ ?
  732. /*          to exit AAI mode unless AAI is programming the last address or                */. _6 d( t  B* `, w6 d" P* Q/ T
  733. /*         last address of unprotected block, which automatically exits                 */
      s3 _4 i0 N8 E
  734. /*         AAI mode.                                                                                                                        */
    : {' ~9 W1 h8 a1 Y5 U
  735. /*                                                                                                                                                */
    % @0 P% F, a$ K7 E3 g. t
  736. /* Input:                                                                                                                                */
    8 S# a3 o! _( G
  737. /*                                                                                                                                                */
    " j7 |: y. G' Z" |& U- _1 V( L+ m
  738. /*                byte1:                1st byte to be programmed                                                        */  h9 p& j& w, W  G# i
  739. /*                byte2:                2nd byte to be programmed                                                        */! Y5 B; f, O  y9 V2 d1 U4 ~
  740. /*                                                                                                                                      */
    + O  Y% s2 D% u$ j' c
  741. /*                                                                                                                                                */
    8 a  j, c2 J% [: r) e
  742. /* Returns:                                                                                                                                */6 C: @) w( ^. t  u8 o3 Z
  743. /*                Nothing                                                                                                                        */  h- \8 x, \3 Y8 A
  744. /*                                                                                                                                                */
    . ]4 m* F9 C" l4 v% }" P
  745. /************************************************************************/9 l1 Z! u& @+ a! f$ k+ e( V) T
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2). s2 G% V$ H2 s7 G
  747. {
    6 `; S) }- \' ~# J; [4 h. @
  748.         CE_Low();                                        /* enable device */
    ! m5 }8 ?; `; d2 f! ~* E
  749.         Send_Byte(0xAD);                        /* send AAI command */
    ! v6 g. W7 l/ I0 Q7 `
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */0 U3 A& D, X4 F& d9 {
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    + ~5 G" @& v# x/ k  d' N
  752.         CE_High();                                        /* disable device */- ]% u: k" }8 o& @$ P
  753. }$ F& G% l* e/ C/ S6 s0 r

  754. , P2 V8 P, z; {7 a' ?$ m
  755. /************************************************************************/
    ) z$ c5 y1 ~: M% o& v
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    7 Z! O, S# ]# y9 e
  757. /*                                                                                                                                                */! ?  w( ^/ p7 R. K6 D8 U& W
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    3 b9 D% \0 H% ?$ ~3 ~
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */
    6 H* B" m5 ^' T( o$ W
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    9 l6 h0 O' k/ v1 t0 j) e. Q5 J6 G
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */  B. m9 R( _! q1 |% e3 m; M! E* l
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */
    - ]" @5 ^2 G5 R& R
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */1 i( w* y7 ~" H# I, u
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */
      O# z% `4 S+ m' A+ d1 ^
  765. /* Assumption:  Address being programmed is already erased and is NOT        */# b# r4 Y- ?) a8 P: ?0 X
  766. /*                                block protected.                                                                                */
    4 a1 P1 N+ m% G, V8 M7 Y& X
  767. /*                                                                                                                                                */
    & \' }6 c# x5 y7 Y1 n) B; B# @
  768. /*                                                                                                                                                */
    8 i1 w, }+ E. R9 F1 {& F
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    2 ]4 F1 V' _* ~1 V7 A
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    ' X2 i" y$ \. v6 t
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */: o& T$ q. V9 \  N4 [
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    6 B' M( D8 s6 A" ?% x
  773. /*         last address of unprotected block, which automatically exits                 */
    9 v' ~5 Z7 H, i0 a  D
  774. /*         AAI mode.                                                                                                                        */+ |9 v. N( n# x+ o+ O0 `+ C0 W
  775. /*                                                                                                                                                */" i) G# g) \- y, a$ S# t  M
  776. /* Input:                                                                                                                                */$ D% e5 e' _1 i0 @7 s- H+ `5 J
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */# I8 d8 U7 W. j7 i! k
  778. /*                byte1:                1st byte to be programmed                                                        */
    ! V) v; d% F) D$ T% B& ^7 N
  779. /*      byte1:                2nd byte to be programmed                                                        */
    - D& r6 W% U/ `* {9 C: O& r
  780. /*                                                                                                                                                */9 f. D1 A' |- J# @" F. P+ s* p8 R
  781. /* Returns:                                                                                                                                */
    . X" j5 Z/ J! J9 q, N+ ~  M
  782. /*                Nothing                                                                                                                        */
    : I9 u5 ?2 s# j; E& N
  783. /*                                                                                                                                                */
    4 D: j+ Z# d& F3 N: d! W+ X8 f- M+ h
  784. /************************************************************************/0 Z* l7 \( a: v5 Q# \; Q
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2). O, W# v% B' a  k8 [0 w  h+ E
  786. {
    1 K/ v9 n$ ]" n1 W& {! H( V
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        1 ?0 K; S: E9 z6 W- I# ]; m
  788. & `% u+ ]1 `" C8 Z3 F# O
  789.         CE_Low();                                        /* enable device */
    9 M5 A; V7 D- q- F3 D4 L
  790.         Send_Byte(0xAD);                        /* send AAI command */
    . W) }+ F% J& ?
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */& T: x2 g# }  d- Y9 z
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));( A" q+ n) G% z! t, H3 b, J
  793.         Send_Byte(Dst & 0xFF);/ v7 a7 _; n8 e( E
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        , e. N! c! C) M. o& Q
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    0 V* Y% z. i% N. t6 \- Y. ^
  796.         CE_High();                                        /* disable device */" B2 d! \: n" v0 |
  797.        
      p( `* }3 N. t
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */
    0 y8 l, |% Q: `/ g& [% y% ^3 I9 f
  799. 0 A. o: y, @/ n2 G2 M2 I
  800. }2 z# D4 t6 w$ S! k9 }

  801. ( k1 }9 Q0 C: x2 R/ @1 B. q
  802. /************************************************************************/
    9 T, U/ M7 O) I$ T& H
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
    0 Z+ A0 y3 j: |( Y& w
  804. /*                                                                                                                                                */
    $ c- B1 T& i' w* s: A- G! w1 a1 Q
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */8 o/ R3 M# S2 A0 d
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */+ v/ ]- I3 Q. i9 e! c1 k" m% G
  807. /* AAI programmming is completed.  It programs consecutive addresses of */
    0 A* f- I+ {! y
  808. /* the device.  The 1st data byte will be programmed into the initial   */
    0 S; d9 B# q( W1 U! M, T' v+ A
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */1 |% [# Q  ~8 Y9 R, Q7 Q
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */
    $ |. j" j) e' ?# k5 C9 `" k1 Y
  811. /* used after Auto_Address_IncA.                                                                                */5 e6 H$ c# h7 ]7 Y6 b, P/ m8 j+ @
  812. /* Assumption:  Address being programmed is already erased and is NOT        */  v* u1 T4 D, o: X9 z4 @
  813. /*                                block protected.                                                                                */  Z4 q* D& c. x7 H& C
  814. /*                                                                                                                                                */  G$ U' F/ }% `7 l" U) p
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    9 d: k2 `- Q' D- @6 l1 x
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */; D7 f+ H! S5 B* h' a; [" h
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */! s' Y1 J4 q& C# a0 q' Y" M
  818. /*          to exit AAI mode unless AAI is programming the last address or                */& V+ n& X6 b7 m: s0 u
  819. /*         last address of unprotected block, which automatically exits                 */
    + i* ~1 N3 w5 _9 {2 v" q4 l2 A
  820. /*         AAI mode.                                                                                                                        */
    - ~1 i8 Y  h- W! Z, J" l8 H
  821. /*                                                                                                                                                */& h0 J+ L2 Y; h' |' U
  822. /* Input:                                                                                                                                */' w/ Q* [, M- |) P% A: z8 K3 x9 Y
  823. /*                                                                                                                                                */8 O* C5 t. h9 A' a
  824. /*                byte1:                1st byte to be programmed                                                        */
    5 Y! E# v9 ?3 `# D
  825. /*                byte2:                2nd byte to be programmed                                                        *// Y9 `) x0 s4 w0 s
  826. /*                                                                                                                                      */
    ( H/ G. t! a' E1 I7 E0 i
  827. /*                                                                                                                                                */
    & {, P* P  d* q7 |  L$ W7 ?
  828. /* Returns:                                                                                                                                */
    " ?- b9 d) M( e% z* j
  829. /*                Nothing                                                                                                                        */; q* y5 F# Q1 ]6 o
  830. /*                                                                                                                                                */
    / h4 Q( x' l3 Y) v( b- o% l. l" {
  831. /************************************************************************/) K. b0 K% c- U8 J: L& I
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)$ Q, L0 s$ {3 |6 G" X
  833. {
    4 [( K" a/ i( \
  834.         CE_Low();                                /* enable device */
    . S4 \5 p2 @$ ?! y; {' w- d
  835.         Send_Byte(0xAD);                /* send AAI command */% w. q& d" O# S2 H
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    * ^6 O7 I/ K$ ?/ l
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */" r" v+ G9 v# @
  838.         CE_High();                                /* disable device */3 ?6 ]- @+ Q5 H2 o; n4 @

  839. 2 y8 {% G, e5 a3 |+ X7 T2 O7 p- X
  840.         Poll_SO();                                /* polls RY/BY# using SO line */
    % Z1 U) \' J* s" E+ a  P

  841. 1 J; Z* |; U# f+ @9 ^* E
  842.         WRDI();                                 /* Exit AAI before executing DBSY */* a' q& }( s# \, d, U+ ^% Q
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */
    - T; t0 Z( U# |0 n& M; r
  844. }
    . j! o7 A* |% O2 f
  845. - ?/ p; v# `# g6 }' G- `
  846. /************************************************************************/. h2 j2 R& T# S+ h- {. i
  847. /* PROCEDURE: Chip_Erase                                                                                                */
    ! W0 l  o, v3 S
  848. /*                                                                                                                                                */7 c, K8 J3 e: G9 l7 e
  849. /* This procedure erases the entire Chip.                                                                */
    3 z6 J: g/ [* L2 ?
  850. /*                                                                                                                                                */
    2 N  ~$ F: z- x8 z# P. E. y
  851. /* Input:                                                                                                                                */% p  k9 q$ H( Q1 u0 \% M  i6 U  N4 W
  852. /*                None                                                                                                                        */# u" Y# I9 F. y
  853. /*                                                                                                                                                */. X+ d# w1 D: W1 ?$ s
  854. /* Returns:                                                                                                                                */
    ( D+ c7 x9 h; O0 p' J
  855. /*                Nothing                                                                                                                        */) ^7 l0 r+ T: e( E
  856. /************************************************************************/6 i  e" \3 ?4 e
  857. void Chip_Erase()
    9 O% f7 ^' M6 L+ R5 W) f( l
  858. {                                                8 _! f; ~3 e$ s& v2 Y0 J
  859.         CE_Low();                                /* enable device */2 V# m* O9 z5 a8 b' U/ u, }* Q
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */
    & \( K" f! L' N7 L4 {' }7 b
  861.         CE_High();                                /* disable device */
      R/ W, z4 s! C
  862. }
    0 V( B" U& p  `& q( e: Q

  863. 0 h  h( G9 H' g( S" N/ S# u7 ?. S
  864. /************************************************************************/' e8 C( G- ]6 ^) D4 M
  865. /* PROCEDURE: Sector_Erase                                                                                                */9 D1 e& k7 D, u+ G
  866. /*                                                                                                                                                */( }" t( U, m7 U( }3 r$ m
  867. /* This procedure Sector Erases the Chip.                                                                */
    5 [1 o/ h8 p6 _2 V
  868. /*                                                                                                                                                */
    & r# A0 Y7 R4 w
  869. /* Input:                                                                                                                                */
    3 m2 K& h" ?3 G' Z7 [* T
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */+ ~7 `' V1 m2 @4 |3 R" G
  871. /*                                                                                                                                                */
    ( o. R, \2 i( Y, @. J
  872. /* Returns:                                                                                                                                */
    3 M# f4 E6 z3 o7 ^+ R
  873. /*                Nothing                                                                                                                        */6 p( [) M; _# p1 v; {7 \2 l! }
  874. /************************************************************************/9 {9 e  Y' W( C) @3 ~. n
  875. void Sector_Erase(unsigned long Dst), q* ^8 y0 }/ d3 n' I$ u0 a
  876. {
      Q% O5 @. d! O: G/ o9 F

  877. 2 p/ |& z6 D- u- c/ k

  878. % M! H. x; j& M# n5 g. J! Q
  879.         CE_Low();                                        /* enable device */
    # q& W) e( `& i& v+ A- _7 ^$ x  t% i2 T
  880.         Send_Byte(0x20);                        /* send Sector Erase command */
    & {, o! R  d' T3 _
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */# Y4 M0 M) V6 G5 |. }
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    7 T# p3 n; C* u8 l
  883.         Send_Byte(Dst & 0xFF);8 N' a4 e5 r! _8 {) y; y4 m
  884.         CE_High();                                        /* disable device */
    - N- q3 a0 v. @7 m* |
  885. }        + c2 _, p3 g7 f2 S( C

  886. # ]+ A7 W% Z; e% M/ x
  887. /************************************************************************/6 m. D. j2 r& X7 F0 ~% h8 J
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */1 k$ U9 e* j# i. [) k) Q
  889. /*                                                                                                                                                */$ E: q6 [6 ^9 U: v# m
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */  g7 X# J' X0 g6 k1 q
  891. /*                                                                                                                                                */) w6 f9 o* K/ c9 A
  892. /* Input:                                                                                                                                */% d1 l: n7 O+ ?  b5 X. x  I
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */" j" l  W0 Q2 Y" m' u) P
  894. /*                                                                                                                                                */( ?7 h( r0 o: l7 J$ O
  895. /* Returns:                                                                                                                                */
    6 J: J( X6 X1 s) v3 ~% S! r) l1 V6 U
  896. /*                Nothing                                                                                                                        */# u6 }# g4 A2 M, e  R
  897. /************************************************************************/
    + c* O( s8 Q3 d6 [8 d3 Q
  898. void Block_Erase_32K(unsigned long Dst)
    1 v! p/ s" b& H; g: F  B5 A4 a
  899. {% t% p$ Z; j! Z; t* L
  900.         CE_Low();                                        /* enable device */
    / I* g0 A1 [" y/ e( b6 Q+ R
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */
    . D" g- ], R/ |3 ?
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    % I  |; c' O% \" t6 `4 `# ~, P( o
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ! G3 v$ w3 g! Z$ w# C
  904.         Send_Byte(Dst & 0xFF);
    4 o- Z+ N2 y7 {5 ~! g
  905.         CE_High();                                        /* disable device */
    % X: p. P% b" D7 C/ T/ R2 j' L, V$ b
  906. }% }( j# ~% F' h; {+ i: I
  907. # |' j; |/ M, d! r4 s% u
  908. /************************************************************************/# D+ q  V+ g4 e( B3 ~
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */1 a( u9 z9 I" P: \. [1 l
  910. /*                                                                                                                                                */
    : Z* i+ r# R2 i* s/ @5 e
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    $ T. G4 `; Q( Q* ^5 q6 z
  912. /*                                                                                                                                                */0 ?5 e4 c1 A; ~' H7 @& b
  913. /* Input:                                                                                                                                */7 W8 R: O4 Q5 a+ n! [& v# E: s8 Z
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    + |# G' l$ \7 \- h
  915. /*                                                                                                                                                */" E6 Q$ K8 L3 B8 x1 m  \1 G
  916. /* Returns:                                                                                                                                */) b5 W, U8 V8 e
  917. /*                Nothing                                                                                                                        */0 b) d& F3 J2 q+ [, I
  918. /************************************************************************/, F# R6 E* d0 h# \3 o- d
  919. void Block_Erase_64K(unsigned long Dst)
    . W9 o+ y4 C& z6 D
  920. {5 i8 m- C1 T/ o% ?# V9 N% t! o
  921.         CE_Low();                                        /* enable device */7 J; P- E* E7 J; l; k
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */: z$ b; R2 b  D$ W9 y6 P
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    ( v3 B- B& w; j/ m/ a  c$ ?
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));# }1 ]9 V2 b& L* k5 A8 U  _' B
  925.         Send_Byte(Dst & 0xFF);6 ^# f" s* W9 m6 S  ?: v
  926.         CE_High();                                        /* disable device */. T3 t. l2 j+ }. ?$ h
  927. }
    $ V) x% i: U3 ^4 M1 E5 i0 M& x: p

  928. ' l4 g% a: U9 @  v6 u: {. f
  929. /************************************************************************/# C3 `; u1 Z+ X" n( Z
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    ; q2 X& d2 b/ j5 [8 ]" E
  931. /*                                                                                                                                                */
    4 A  O. J* R3 B
  932. /* This procedure waits until device is no longer busy (can be used by        */
    & t% @! Y* w. A. h
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */
    $ }2 L5 @$ B) x. O& [8 h! o
  934. /*                                                                                                                                                *// [6 ^5 t5 P4 ~1 u4 s
  935. /* Input:                                                                                                                                */
    * i/ \* u# ~! o  d) v
  936. /*                None                                                                                                                        */7 |, D! S7 Y/ e2 a
  937. /*                                                                                                                                                */
    " A6 N9 d, ?$ j  {; O/ n& `
  938. /* Returns:                                                                                                                                */! p9 p, ?! J& u; p$ r! }8 Y( k
  939. /*                Nothing                                                                                                                        */
    ! h3 ^& s1 ~- B9 p+ K( `3 _3 {8 _
  940. /************************************************************************/2 d1 b( ?5 }* d5 J! ^
  941. void Wait_Busy()
    : o5 j( Y+ J  e, _/ J1 `
  942. {
    1 k" |" |' x4 H+ N1 t# d0 ^
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    # u5 X$ i! Y0 r% Y2 Z
  944.                 Read_Status_Register();  {9 X1 H; _& p& Y
  945. }# e( l% c3 Q2 v0 W
  946. # |9 d0 `/ z7 z' O
  947. /************************************************************************/
    $ T  a6 y6 T+ O, c
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */, _* i1 _) A( a( J
  949. /*                                                                                                                                                */
    & `! U& x/ ^$ k" _' R( g5 R
  950. /* This procedure waits until device is no longer busy for AAI mode.        */8 @! f. X( z: S" N  T
  951. /*                                                                                                                                                */
    " z! W6 N/ ?, V) f0 }. d  Y
  952. /* Input:                                                                                                                                */( s! m' W9 H; R8 P3 ?$ T
  953. /*                None                                                                                                                        */
    ) a3 U" V8 t' `5 S% H
  954. /*                                                                                                                                                */& [; i5 r7 S! W
  955. /* Returns:                                                                                                                                */9 o4 O, ~3 L) T; I9 _* U$ Z: a
  956. /*                Nothing                                                                                                                        */
    ! A6 Q: U9 I: j  T; c2 V5 ]
  957. /************************************************************************/1 P1 i* d2 y: l1 i+ f$ y
  958. void Wait_Busy_AAI()
    * Y9 m- f5 F5 t
  959. {
    , w- K( _4 L# W' q( B) g! D& _
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */$ k" P8 G  m! E: v- X3 }5 n0 j
  961.                 Read_Status_Register();
      B) z2 y# I& l6 T+ V2 C/ ~. |
  962. }; b0 k- V$ p3 H3 f( U

  963. $ y) q$ ^2 J$ q1 J, o. s# q
  964. /************************************************************************/  a' n% f+ p5 M* ]5 E4 Q- [
  965. /* PROCEDURE: WREN_Check                                                                                                */
    ' ~' @# f) b2 y: E) I6 B# Q- ]
  966. /*                                                                                                                                                */
    8 d0 L9 [/ \+ I0 L6 g4 x
  967. /* This procedure checks to see if WEL bit set before program/erase.        */7 s. i* g- a0 v( Z; i6 I3 T& L
  968. /*                                                                                                                                                */
    9 ^; Y/ l! Q6 [/ ?; W
  969. /* Input:                                                                                                                                */
    1 L# }# R% v- `; _6 M" A6 g( @( W1 `
  970. /*                None                                                                                                                        */9 k- Q5 s+ M- @1 F( U* s) V& ^
  971. /*                                                                                                                                                */) ~; |) Q" V+ q- m9 Y$ A
  972. /* Returns:                                                                                                                                */# F7 C( F% Q, p
  973. /*                Nothing                                                                                                                        */
    1 @  Q* U- w/ v2 a: h
  974. /************************************************************************/% Q. d) R! Q( {
  975. void WREN_Check(); e( M. a+ |( n2 L
  976. {. _+ {0 s( Y1 M% m& s9 t% c
  977.         unsigned char byte;0 T( G5 {% ?+ a7 Q6 l! ?0 F
  978.         byte = Read_Status_Register();        /* read the status register */
    - @. x, S7 w9 e1 j  ]% I
  979.         if (byte != 0x02)                /* verify that WEL bit is set */
    ' Q/ _9 W3 ~7 b
  980.         {0 i- }; b; K# E1 b
  981.                 while(1)
    . c+ R5 B* p6 S8 j2 _; D  a
  982.                         /* add source code or statements for this file *// Y* W2 o9 N* Y- o! G' l
  983.                         /* to compile                                  */$ _1 O8 p+ Z1 o1 i4 y" J
  984.                         /* i.e. option: insert a display to view error on LED? */
      u: v% Z/ t( @3 N1 X' \
  985.                  / ?3 P  S% h$ \  E  p
  986.         }
    / [; ?. B, N6 }# D  _
  987. }
    6 w" @0 b2 I9 p$ c/ ?# Q

  988. ' W. o% D( ^2 f+ J3 q1 U+ I# k+ ^
  989. /************************************************************************/
    7 y! s( r2 y, F; F
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */- W$ q- a2 ^/ d
  991. /*                                                                                                                                                */0 P( q9 B* b! [6 X7 d5 |: o
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */. ~& P+ K4 \5 _3 }" t1 c, l
  993. /*                                                                                                                                                */
    7 ]1 z+ `1 S: `' n" @4 U
  994. /* Input:                                                                                                                                */
    " B( g. ~0 Y, K3 M" ^, V
  995. /*                None                                                                                                                        */8 [  M; }: J# e% U
  996. /*                                                                                                                                                */! h- I' d+ ]4 w3 G9 |$ j
  997. /* Returns:                                                                                                                                */
    & S$ C! }5 U9 C0 S
  998. /*                Nothing                                                                                                                        */
    2 w& T0 Q, s! \' v
  999. /************************************************************************/
    . t0 L4 ~  t" Y7 y; R: ~
  1000. void WREN_AAI_Check()
    + z  N$ ?/ ~$ N2 _' c; b6 C
  1001. {
    2 I9 d( y  Z: P% t3 i
  1002.         unsigned char byte;& q1 K9 v+ ^  v
  1003.         byte = Read_Status_Register();        /* read the status register */1 M1 G% }/ c3 H' F: l
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    ! n6 J4 r0 R( ], F3 e
  1005.         {
      F, B0 a- }/ _- L* q( f' F0 ^8 _
  1006.                 while(1)                3 p, s% d- p8 e6 Z1 [
  1007.                         /* add source code or statements for this file */3 y' W' N' `- C) e/ `
  1008.                         /* to compile                                  */' Y$ C5 |1 Q) i; ]# _; `
  1009.                         /* i.e. option: insert a display to view error on LED? */# m$ I- C' z7 {
  1010. . C. A8 L" S9 v4 a' e
  1011.         }
    7 B% V. U" M- [7 ~$ p) g
  1012. }
    4 h  u6 Y% i/ d2 F5 d- a4 Y' w, S

  1013. 1 Q' N: R# h. ?
  1014. /************************************************************************/% T6 f% N7 F1 v* P7 E& I6 H
  1015. /* PROCEDURE: Verify                                                                                                        */
    1 k' L4 L) W0 }6 B9 q- q& b
  1016. /*                                                                                                                                                */
    ' Q7 ?6 r2 ]/ J% ]# a0 i
  1017. /* This procedure checks to see if the correct byte has be read.                */0 d! u) K3 D7 g8 A1 N& a1 |
  1018. /*                                                                                                                                                */
    & _2 t; P: N0 i5 o' c* G* y* p
  1019. /* Input:                                                                                                                                */
    1 G0 Y% e: h4 `- }
  1020. /*                byte:                byte read                                                                                        */% f0 ~, l- v0 s4 s. A6 ^
  1021. /*                cor_byte:        correct_byte that should be read                                        */2 M) |8 T. J7 h+ Q! z
  1022. /*                                                                                                                                                */# O% d% d% v7 ?' t8 R5 Z
  1023. /* Returns:                                                                                                                                */
    ! ]6 T( D" X8 _5 b
  1024. /*                Nothing                                                                                                                        */1 u; c- b+ W9 G8 S# ]
  1025. /************************************************************************/1 j, D/ c" u& G4 I$ Z& W7 k
  1026. void Verify(unsigned char byte, unsigned char cor_byte)+ ^8 y8 M" [+ k) d/ L
  1027. {1 l3 w2 L% ?5 V$ {& q0 T0 L4 S* ?5 P
  1028.         if (byte != cor_byte)" e' N9 |% U: q# O- s
  1029.         {  p7 _% c: W# W1 Q
  1030.                 while(1)
    # Y* {" r8 `8 s# g. F
  1031.                         /* add source code or statement for this file */6 a" b% M, F' F3 h7 v! Y
  1032.                         /* to compile                                  */
    6 B6 x2 R5 w# k* l5 u' w; ?% K
  1033.                         /* i.e. option: insert a display to view error on LED? */- Z1 H1 P. Y/ ^7 Z- L) U
  1034.                
    5 I9 G5 k, K- r  R$ N1 m
  1035.         }
    , Y5 V- t) u, K: R4 l5 r6 D3 t
  1036. }
    ( r( i# n; S2 c
  1037. : v% {) S7 g6 y5 {  r4 S/ c- R

  1038. ( M% c( i) E  ]& O$ A" S: f
  1039. int main()
      S- ^  @+ I7 U! B/ i, d& a
  1040. {) {, |( i$ ~. t: g( `
  1041. ( ?' }% k% }, C
  1042. return 0;5 O1 x1 M, V+ Q& R
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
0 W/ `1 {1 D5 L3 R- ?( y   main()
+ z9 F) s, p% k   里面怎么是空的呢?
& ]$ a1 `  N3 d& u, u+ Z   发一份给我吧
3 _! v. _! O/ b5 i' t' e1 Z4 xmail:luyijun2005@hotmail.com
/ ?! V! k# r  x咯。。。。
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。
( u% E  i2 l/ j; @! c( Y; {" `% S+ o- |9 P- J
[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。+ {% c: b4 f; d; [
EC的代码在哪跑,你看DS的说明,每个EC都不同的。+ p- |/ }5 A- r
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?( u, C+ B  u4 f3 N/ P: R& x& i
上面几个问题是你没看任何东西而白问。
( z3 s5 u# d& S' K* j; \1 t9 j
0 N& O7 C* p, @- }7 O至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

发表于 2008-1-11 18:49:08 | 显示全部楼层
该怎么说呢,我是抱着很诚恳的态度来问问题的。上面我问出来的问题都是经过认真思考才问的。您站上贴出来的跟EC有关的spec我都看多,而且是很多遍(ACPI不是全部章节都看,因为我是hw)。EC的spec我也看多很多家,因为我们要做EC chip。楼主“上面几个问题是你没看任何东西而白问。”“请问一下,你有静下心来看过spec了么?”这个结论未免武断。
+ A. Y' {! M: f! k1 C3 t( _
$ W: L4 H) [  z1 _) ~0 ]4 V6 O关于SPI flash对SPI接口的定义,我当然知道各家spec里面都有提到,但是我要知道如何才是通用的,我们不是只要支持一款就可以。所以我才会问SPI是否有官方spec。您也知道,做产品是一定要符合工业标准的!1 p+ ~- h1 d! u' l. D3 F/ z2 D

8 B# I0 H3 b8 Z; P关于EC firmware在哪里运行,除了ns有用内部flash的以外,基本都说是在flash上直接跑,并行的flash不会有问题,但是串行的flash速度可能就是问题,因此我会问到“EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。”, q, ~6 ]8 @. O$ o
) s5 h0 |+ I4 N9 a
关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...$ S9 S& I( h. z
& {5 `; V6 w2 B2 D; T% [
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样& \5 J" I- O( `, K0 K' F( W( ?
似乎要把SPI能support 到最大,这EC chip应该有好卖点3 i& \% o$ N# z4 n/ S3 \5 B
BIOS功能要不要强大,也就决定了SPI Flach的大小
2 k4 c) g) m4 A  q; H我是这么想的~让OEM去决定要挂多大!
- h1 u2 q# P8 |) a, }# E; y4 Y如果我司有BIOS工程师就好了~哈
1 F" f) k- i+ i" [! X0 C$ K" IWPCE775应该算很新的东西,来看它支持到多大?6 p+ d* O7 z0 b# k

! R: h4 g2 w2 F( _( |' K( d8 n另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte
3 Z( ~' @- g; A2 P: a其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.& a3 L* I6 {, }3 T2 Q2 V9 r
4 @3 k2 ?* B6 p& j3 x8 a
这份driver收下~希望以后有用到6 l; Z  I" s- f4 k1 i4 @' D
谢谢bini大大
: _' p1 Q+ r9 ^7 O5 h( Z& J
7 p" ]5 B: q% t' l1 @8 o很新很新的新手,如有错误请指正 (准备看第二家的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()
! @0 V2 F0 w3 ^* O; Q{5 Q& E$ `$ I' n  L
        unsigned char temp = 0;$ H# w/ o) t6 z7 o: s" }  J
        CE_Low();  r0 L+ `, b. _& J. |
    while (temp == 0x00)        /* waste time until not busy */3 D& j! Y$ W( A! g' T/ C3 c
                temp = SO;
- _8 R* N( v: P. ~        CE_High();# \3 ?$ O# ?% U! l
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out): d0 ~: h" W; F: a( k7 u1 J( y) J  f
{
- c9 a! e: M1 s6 k+ A- G& V) O        
7 {/ t) |" a" E/ H' K; H& L/ c2 T        unsigned char i = 0;. ]! G$ F* }1 O! `; H
        for (i = 0; i < 8; i++)
5 _; l. L. n5 U6 N        {1 v; `" r& A! e
                : i+ P! S; w5 m3 G) t' ?5 z2 N& T
                if ((out & 0x80) == 0x80)        /* check if MSB is high */6 G* B9 y/ x9 ^
                        SI = 1;6 h+ L# m* c, b0 R  l' Z! v4 X
                else
3 {" k$ x  p* c4 }9 t& W                        SI = 0;                                /* if not, set to low */9 W8 H( B$ h7 N. c* [7 b" I
问              SCK = 1;                                /* toggle clock high */
7 [1 H% _- x" k7 o   题            out = (out << 1);                /* shift 1 place for next bit */
( I9 _, \) o, b' H! o                SCK = 0;                                /* toggle clock low */
" ?" {' a' r8 c$ i  q8 y4 q        }
! _* M% O) q7 x) {0 B% W}
( B, G: c- j& |0 x2 `- P$ W 如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-4-4 18:24 , Processed in 0.113653 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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