找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 53402|回复: 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& X+ H% X' Y: W. n$ s

  2. ) i. u$ G; Y; t
  3. SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory
    ' b- i2 x* U. k4 q# ]

  4. / Q$ |2 g$ I, r. Y: l
  5. November 4th, 2005, Rev. 1.0
    . U) l6 X( `' p. k' j) m

  6. : J% v$ J9 l% h0 [6 v
  7. ABOUT THE SOFTWARE. T( v) u! F9 w, Y- L  ^
  8. This application note provides software driver examples for SST25VF080B,( [' _" ^8 |% X- k9 [
  9. Serial Flash. Extensive comments are included in each routine to describe 9 `5 Q% x0 n. Z$ @# y. D
  10. the function of each routine.  The interface coding uses polling method
    3 k% b! z. r" A4 i6 D
  11. rather than the SPI protocol to interface with these serial devices.  The
    3 M, k. w7 O$ h- [' E% d3 ?7 W* ]0 p! _
  12. functions are differentiated below in terms of the communication protocols
    : d4 J- v% \. {. W; P1 e. @/ V4 q
  13. (uses Mode 0) and specific device operation instructions. This code has been 3 x" ]* {) V: U, B  R& x# M
  14. designed to compile using the Keil compiler.
      X; r9 I" h, F! f. a8 `: h% d, @% k
  15. 8 K: d& i/ o. W2 D

  16. 7 u) h/ X9 R+ _0 \
  17. ABOUT THE SST25VF080B
    $ m% J- C, [, T
  18. - ^7 Q! z# J7 }: x/ }/ u
  19. Companion product datasheets for the SST25VF080B should be reviewed in
    . E: s+ a8 ^$ b! v' D% t
  20. conjunction with this application note for a complete understanding ( W# u) H/ S# z% `. p
  21. of the device.' P# E* H3 J8 }
  22. 5 Q( \: C; r, y
  23. * i' E* Y* [, m
  24. Device Communication Protocol(pinout related) functions:% j7 X! s) g+ g) ]1 R5 n2 y

  25. , L+ D- h! N3 ^2 p/ w, U' X
  26. Functions                                    Function1 _7 d+ E& f: O" y& n* ~
  27. ------------------------------------------------------------------' X, B  n6 f0 X3 w  m% N+ k2 u
  28. init                                        Initializes clock to set up mode 0.
    ; ], L" c4 ~4 c" i8 O$ H* `7 a
  29. Send_Byte                                Sends one byte using SI pin to send and   h$ [! H3 X' [7 _7 x# L! |' ]
  30.                                                 shift out 1-bit per clock rising edge
    , C1 g# z* \; r" W$ O( @5 C
  31. Get_Byte                                Receives one byte using SO pin to receive and shift
    0 E9 E: `$ ]5 D6 z9 I
  32.                                                 in 1-bit per clock falling edge) M; W+ X9 _* }) R; r" ]: Q8 D
  33. Poll_SO                                        Used in the polling for RY/BY# of SO during AAI programming' p- j. k: L6 T. M1 M" E
  34. CE_High                                        Sets Chip Enable pin of the serial flash to high. M6 @0 g( c' P0 L2 V3 V2 A# z
  35. CE_Low                                        Clears Chip Enable of the serial flash to low1 \; w* e! W2 R) {9 e: j% Y0 \
  36. Hold_Low                                Clears Hold pin to make serial flash hold& U' k: t3 I' W5 }! Z1 e+ J+ @
  37. Unhold                                        Unholds the serial flash: W5 Z/ n+ w  A% P" z, R
  38. WP_Low                                        Clears WP pin to make serial flash write protected' A& w( j8 |5 G# \2 R3 g! Y- v  ^
  39. UnWP                                        Disables write protection pin. b# R$ ?, g, s$ J3 G1 N

  40. 5 F) V0 f  s8 G* u- C
  41. Note:  The pin names of the SST25VF080B are used in this application note. The associated test code
    $ o/ g$ T2 ~) C" E$ X$ D) w1 T
  42. will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your1 X0 w/ S0 _/ U. j( T
  43. software which should reflect your hardware interfaced.          
    ! t+ i+ |& U) b( E
  44. & r3 K$ G# O3 H2 A3 Z
  45. 3 }! D! q3 [$ A# [: T# f
  46. Device Operation Instruction functions:' E7 c' `. J* T1 j

  47. 2 x4 W3 z5 K- U) m9 l2 A2 j$ }. Z5 Q  I
  48. Functions                                    Function
    8 q: @- g+ a# @2 t* M
  49. ------------------------------------------------------------------) r3 D  N9 s# X8 e: L
  50. Read_Status_Register        Reads the status register of the serial flash
    0 N. }, b* w- r9 ?1 m0 |" T
  51. EWSR                                        Enables the Write Status Register* r& o) ^5 D7 i9 X* c* K( e% K
  52. WRSR                                        Performs a write to the status register1 y' F7 H' e* g; [2 W
  53. WREN                                        Write enables the serial flash' x( _2 Q$ f$ r; Z% w1 d
  54. WRDI                                        Write disables the serial flash
    % ?- c3 M) ~; l9 w- ]! l; I
  55. EBSY                                        Enable SO to output RY/BY# status during AAI programming: ]& V4 K: Y! {7 z
  56. DBSY                                        Disable SO to output RY/BY# status during AAI programming1 E& ^3 }+ m. M- a
  57. Read_ID                                        Reads the manufacturer ID and device ID) z0 i' S; q) N' h& N/ c3 a- D8 H' e1 d
  58. Jedec_ID_Read                        Reads the Jedec ID0 a2 \9 j; p+ U# A" b5 T
  59. Read                                        Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
    , z- p1 Y# I8 Z4 Q6 P" I
  60. Read_Cont                                Reads multiple bytes(max of 25 MHz CLK frequency)
    " ^' Q% v2 y$ k5 P( t. J8 s9 E
  61. HighSpeed_Read                        Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
    ! v' ]% R5 v% s2 N4 g
  62. HighSpeed_Read_Cont                Reads multiple bytes(max of 50 MHz CLK frequency)
    * R& E- k+ G& i9 E
  63. Byte_Program                        Program one byte to the serial flash
    4 K* |) ]% Q5 |8 ?/ K! v5 G9 y3 K+ u+ R' w
  64. Auto_Add_IncA                        Initial Auto Address Increment process
    5 V7 v6 y" X# ~; t! m
  65. Auto_Add_IncB                        Successive Auto_Address_Increment process after AAI initiation, @+ [8 W& l( o& _
  66. Auto_Add_IncA_EBSY                Initial Auto Address Increment process with EBSY
    - t9 T% C) ~' K* h- g& C9 g4 Z
  67. Auto_Add_IncB_EBSY                Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY; {" j9 [  D6 ^0 h3 I
  68. Chip_Erase                                Erases entire serial flash
    9 |/ u7 [1 z" z4 W: o3 N
  69. Sector_Erase                        Erases one sector (4 KB) of the serial flash; x; U( R' ^9 |! `1 T. p3 b/ |' Q
  70. Block_Erase_32K                        Erases 32 KByte block memory of the serial flash
    2 v" Q. m5 w9 p$ `$ E* r* y3 `4 F8 ^) V; c
  71. Block_Erase_64K                        Erases 64 KByte block memory of the serial flash
    ( c! [6 c5 `: |4 y& A) R
  72. Wait_Busy                                Polls status register until busy bit is low( J: R2 G! ]) \3 f7 R0 @
  73. Wait_Busy_AAI                        Polls status register until busy bit is low for AAI programming
    ) Z3 B8 O; h4 @. Y
  74. WREN_Check                                Checks to see if WEL is set
    7 v. K2 w  T) @4 ?/ p
  75. WREN_AAI_Check                        Checks to see if WEL and AAI mode is set
    5 D7 T+ A( D9 o. g$ O' J) P- N

  76. & }7 o- J! X5 w+ J! X( I$ @- J3 L

  77. 9 ?" Y5 U7 b4 Q4 z. {! I

  78. / J4 q; U5 p- U5 O+ R6 C
  79.                                                                      
    9 ]6 q) s9 z( I* l/ ~  N9 y. [
  80. "C" LANGUAGE DRIVERS % R1 G" b2 X; k, {

  81. & n, R) J: H& L$ H' {: o/ k/ a
  82. /********************************************************************/
    & x$ x+ _% G, I0 {5 p0 x
  83. /* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005            */
    : \+ f7 [, U) P! N( ^, ^
  84. /* Example "C" language Driver of SST25VF080B Serial Flash                        */
    % o) u9 b  }0 l% P/ t: q& H3 K0 S" P
  85. /* Conrado Canio, Silicon Storage Technology, Inc.                  */4 Y6 |$ |9 N* `$ {, B# o
  86. /*                                                                  */, F6 k0 p3 L. x& V. v0 r
  87. /* Revision 1.0, November 4th, 2005                                                                          */   
    % B8 ?+ x. r- Q" t7 f8 Q5 z5 Q
  88. /*                                                                  */
    . X- i9 |, j. B- o; M
  89. /*                                                                                                                                        */
    $ j# u# F1 g3 @0 _* c: n
  90. /********************************************************************/
    " s' S! j8 N2 B! H" u

  91. 7 t+ `! J/ a% c3 ^) J
  92. #include <stdio.h>
    1 j: d0 S# A) t! ^  G7 X7 g) g
  93. #include <stdlib.h>
    + I; h/ ~! s8 I3 ^$ R
  94. % e# h) }  `' n. r2 d
  95. /* Function Prototypes */
    # W2 o7 i* B! p$ s

  96. 3 r* S) N  B: n2 J9 r9 m( u
  97. void init();2 I* T( K( y; `) H* l; i
  98. void Send_Byte(unsigned char out);
    # W7 @8 W5 \2 N: v/ I& Y
  99. unsigned char Get_Byte();
    % V3 L8 e) v, J) M, Z+ n6 L( C7 T% [
  100. void Poll_SO();
    3 A' T( [8 N4 S( {$ d
  101. void CE_High();
    . d5 U0 O  l7 C5 D# t9 k" _4 i
  102. void CE_Low();
    . q  q' Q& S+ S" L& _7 Q
  103. void Hold_Low();& e3 t6 X* B" z- U1 A8 d/ t/ Y
  104. void Unhold();. ]" U5 g! o$ v  T0 M2 [- k
  105. void WP_Low();" f$ Y+ q, N% p  y' U
  106. void UnWP();! r' A9 F# F. {8 d% B, Z8 S
  107. unsigned char Read_Status_Register();+ m$ c( r( [: }$ w1 ^
  108. void EWSR();
    * K/ \0 T  ~* |% v' f
  109. void WRSR(byte);+ _. Q; k! |# K2 t% p
  110. void WREN();
    ) ~" p- L% Q6 {. u- J4 B- {
  111. void WRDI();
    ) h, G6 Z/ I4 v5 F" Y
  112. void EBSY();
    5 ~/ _% l$ ]0 k! c7 d# S
  113. void DBSY();
    / ^* B& B+ s4 l: u7 n
  114. unsigned char Read_ID(ID_addr);  D" c/ T; n$ i7 O" L
  115. unsigned long Jedec_ID_Read(); ! s9 }. q: z- _9 H
  116. unsigned char Read(unsigned long Dst);% t+ _! E& @4 N+ t3 w& d8 @2 c) d! a
  117. void Read_Cont(unsigned long Dst, unsigned long no_bytes);* M! f' Q9 L' w' Y& E! R( \/ L6 S
  118. unsigned char HighSpeed_Read(unsigned long Dst);
    ) k5 r( p& C! A5 T! @! \0 j
  119. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
    ! Y0 `$ Y5 I6 F
  120. void Byte_Program(unsigned long Dst, unsigned char byte);5 T0 L. J5 V7 C6 m2 N7 @: @
  121. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);9 i* f. v7 I# a$ X& V
  122. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);& d+ b, O$ k9 I0 h" y
  123. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
    4 A# I, v) ~! N1 H5 y+ {
  124. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);/ U, V7 b: K8 }1 J
  125. void Chip_Erase();% R; W/ D6 h" `* [# z8 x# c. A4 Z( M
  126. void Sector_Erase(unsigned long Dst);9 t7 }/ I- |. Q7 l0 I' D
  127. void Block_Erase_32K(unsigned long Dst);4 ^$ k* Q0 o+ D4 `" V$ k
  128. void Block_Erase_64K(unsigned long Dst);( K: ~% R7 m) Z; m* d
  129. void Wait_Busy();
    ! w# j, o0 `7 A1 E
  130. void Wait_Busy_AAI();) |: N1 q' I& K6 @3 A$ `
  131. void WREN_Check();1 E. l7 e( D6 k+ L4 Y: V' j* Z
  132. void WREN_AAI_Check();- Z3 V/ u/ m( {9 I% e: X6 Z
  133.   U% }( `, e: K
  134. void Verify(unsigned char byte, unsigned char cor_byte);7 S2 W2 h4 _, a2 S! z' `- A
  135. ! B5 C( |7 _" E* _1 H
  136. unsigned char idata upper_128[128];                /* global array to store read data */
    & N9 `- f3 N& K+ I  f
  137.                                                                                 /* to upper RAM area from 80H - FFH *// y$ R+ x0 _9 Q+ X6 J! O: H
  138. + }+ _& C) S8 N% H1 K. h
  139. /************************************************************************/  _. V: H; R# C! {( |
  140. /* PROCEDURE: init                                                                                                                */! D2 ?/ e, d6 j  \; B6 G
  141. /*                                                                                                                                                */
    ; N; x6 l0 A7 {0 v
  142. /* This procedure initializes the SCK to low. Must be called prior to         */4 S4 C' q; r; `8 w! N  U
  143. /* setting up mode 0.                                                                                                        */
    + q2 t6 Q" T, B& @; o# b, w) f
  144. /*                                                                                                                                                */: F' C7 M2 M- v+ B3 E/ Z  U
  145. /* Input:                                                                                                                                */% n  e  ~7 t- {6 O7 |, j7 z
  146. /*                None                                                                                                                        */
    : x1 Q# d: Z% I. g6 Y9 D' \, l$ ~
  147. /*                                                                                                                                                */
    ' v6 V, D. }7 \0 L- F. H( d( k6 z5 ~
  148. /* Output:                                                                                                                                */; M' `* |7 d7 Q& I
  149. /*                SCK                                                                                                                                */
    1 y- ?' W# i$ F3 y3 G& `
  150. /************************************************************************/
    8 B7 B9 N( M5 I- ^9 O7 U! _
  151. void init()! P( s( E$ B6 {2 Q% O
  152. {' I. G3 {& W, P7 H& o2 ?
  153.         SCK = 0;        /* set clock to low initial state */# X! ^, i. ?: v; i7 i- p; q
  154. }
    ; @0 ~4 i; U( l' m
  155. , A" S" l+ Z' `8 }% U2 F& `) h
  156. /************************************************************************/' J1 r9 m* X; u8 w6 X
  157. /* PROCEDURE: Send_Byte                                                                                                        */
    % y2 K1 u' o8 [9 _
  158. /*                                                                                                                                                */
    " ?5 e; X' s2 E- e) L% z& _
  159. /* This procedure outputs a byte shifting out 1-bit per clock rising        */* F7 m9 ]) e* R+ E) I
  160. /* edge on the the SI pin(LSB 1st).                                                                                */
    7 i& ^2 q2 u% d& N9 U' K3 e+ z% Z
  161. /*                                                                                                                                                */
    8 T7 A6 [2 ~2 }. |
  162. /* Input:                                                                                                                                */
    / p) K5 i1 J7 W) F8 a
  163. /*                out                                                                                                                                */9 J% {3 O# g% p* Z3 Z; a( c
  164. /*                                                                                                                                                */) L/ ~$ g, @" }1 C% f' c# [
  165. /* Output:                                                                                                                                */
    ; ?0 e; P2 z; ^0 E; g0 N2 m' [/ R
  166. /*                SI                                                                                                                                */+ v& E% F0 h' H6 J( Q5 {0 E
  167. /************************************************************************/
    ; k2 x3 g6 j# s- V5 M4 R
  168. void Send_Byte(unsigned char out)5 d5 O4 _' U! Z- Z: {1 L- x- S
  169. {
    ' {' k0 z  V+ i6 p$ E! R# n
  170.        
    % ?3 i  y+ V3 U* B* u
  171.         unsigned char i = 0;2 i# t" g1 J  a8 \% a) V7 l
  172.         for (i = 0; i < 8; i++)2 O# `5 q+ D3 B" W1 c/ ~
  173.         {. d; s+ M8 T, m  ?( H
  174.                 0 V: f1 v$ N: x1 W/ Q$ N  {
  175.                 if ((out & 0x80) == 0x80)        /* check if MSB is high */! o7 U! a5 r0 o' \
  176.                         SI = 1;
    / m9 o# V( F+ m& V( L
  177.                 else/ h2 s/ G! l$ n" P; m! Z1 }5 q
  178.                         SI = 0;                                /* if not, set to low */
    ; s" a; e5 w1 ~5 Q7 |( b
  179.                 SCK = 1;                                /* toggle clock high */! r, v+ c  g( a* k
  180.                 out = (out << 1);                /* shift 1 place for next bit */
    3 `9 d1 K, G) Y' N- t; R5 Z( ?0 [
  181.                 SCK = 0;                                /* toggle clock low */
    4 e1 d; H4 m+ `
  182.         }
    6 ~* {7 R' n0 A! p( g
  183. }$ a5 `4 r: U0 A  L; F1 d) K
  184. # K0 a- w/ _8 R) M
  185. /************************************************************************/  Q9 `* Y" U$ G- J- \
  186. /* PROCEDURE: Get_Byte                                                                                                        */, k" P% w% F9 `' W, }
  187. /*                                                                                                                                                */: V( v: t7 `$ z) y
  188. /* This procedure inputs a byte shifting in 1-bit per clock falling                */
    # x6 C/ O/ K0 v; N. o! F0 x0 f
  189. /* edge on the SO pin(LSB 1st).                                                                                        */$ y+ B" x# I! }
  190. /*                                                                                                                                                */
      a* W7 D5 m0 Z% s2 O7 `; _' U
  191. /* Input:                                                                                                                                */
    . S( G7 X! K7 d$ h# h6 f% @; c
  192. /*                SO                                                                                                                                */2 K$ ]) i. o1 |5 E0 m
  193. /*                                                                                                                                                */# X) |$ I5 _0 c4 G* m
  194. /* Output:                                                                                                                                */
    " N# v/ E) ?9 o8 _7 A" r
  195. /*                None                                                                                                                        */
    7 W" f1 T2 \. }* t4 {3 D
  196. /************************************************************************/% w* x: K4 V2 B; G# @) r
  197. unsigned char Get_Byte()
    ; G  W7 g: E. Q3 V
  198. {% q4 Z" n& f+ [% E/ q
  199.         unsigned char i = 0, in = 0, temp = 0;
    $ K5 q1 H) x  @5 H
  200.         for (i = 0; i < 8; i++)* i. r& M0 B) M$ Q4 g
  201.         {
    " X, B9 R0 R7 u( s6 U3 O
  202.                 in = (in << 1);                /* shift 1 place to the left or shift in 0 */0 X# r9 w5 l3 t, C" o. D
  203.                 temp = SO;                        /* save input */* ^: m7 W. L; b: {* i/ |. E
  204.                 SCK = 1;                        /* toggle clock high */8 i  |4 r, ]4 x6 p+ F
  205.                 if (temp == 1)                        /* check to see if bit is high */: g8 e" v, D. O: G, O( J
  206.                         in = in | 0x01;                /* if high, make bit high */
    # i2 v9 V. k2 E3 ?& F, j6 _
  207. 2 M3 H% _: s/ }" ?- c
  208.                 SCK = 0;                        /* toggle clock low */
    ; V- w5 _- a5 {4 ?, n! [: W
  209. * S9 X# k1 `: c  Y4 X4 X& X, d; o
  210.         }
    + W! |6 U9 c6 p: Y
  211.         return in;
    - {/ B% k- v1 Q: ?: Z. h( h
  212. }
    5 @# A+ T: ]( N% P9 M% m0 r/ N5 n

  213. * U* _: c% |+ Y" b- q5 L
  214. /************************************************************************/) X' [, Q( b1 `; p/ L' u8 Y
  215. /* PROCEDURE: Poll_SO                                                                                                        */4 M4 c; `( b# i0 F
  216. /*                                                                                                                                                */
    ) ], n9 v9 T9 D/ _# x
  217. /* This procedure polls for the SO line during AAI programming                  */
    1 J3 l" P; D1 ~6 g5 ]0 Q3 P( Q$ Z* n, A
  218. /* waiting for SO to transition to 1 which will indicate AAI programming*/
    + I& H4 b6 G5 R( {5 Q
  219. /* is completed                                                                                                                        */2 G9 n" R+ O, @# I' N
  220. /*                                                                                                                                                */
    / q0 ]- n, Z# Q6 A9 P$ z& O6 g
  221. /* Input:                                                                                                                                */
    5 R# z8 V' I9 Z) b2 n3 ]4 ]
  222. /*                SO                                                                                                                                */
    2 d- @$ L. I6 t5 V2 K
  223. /*                                                                                                                                                */" S/ i4 G/ i  i
  224. /* Output:                                                                                                                                */
    $ q3 a- E0 Q4 W& C" T; e+ P
  225. /*                None                                                                                                                        */
    7 s- u, t4 D7 D3 v. G  o
  226. /************************************************************************/8 I& a4 K. `- }1 y3 J- b
  227. void Poll_SO()4 g; s  V. w4 K# z
  228. {: d2 J$ {) ]6 Y& p" L
  229.         unsigned char temp = 0;4 Z9 n, R; v) b- U+ B! o- R
  230.         CE_Low();
    9 O4 f- {# \, t( e. P+ b) v9 P& z
  231.     while (temp == 0x00)        /* waste time until not busy */
    - V( m7 E/ o5 X  ^' t8 Q
  232.                 temp = SO;  N7 ^! L3 U# o( M5 f% ]. _
  233.         CE_High();0 {! u* t3 K8 C+ p
  234. }! v+ x& D' @) I3 `1 D6 g% H6 _
  235. 6 J* J4 g- t0 }& o  v; v9 N  w
  236. /************************************************************************/
      Q, O6 w% n- m) {7 _8 [
  237. /* PROCEDURE: CE_High                                                                                                        */
    9 `6 w8 K! [0 {
  238. /*                                                                                                                                                */* m" m, @- R8 {+ Q. [- r
  239. /* This procedure set CE = High.                                                                                */3 J0 V! J& @* J& G0 o6 G$ D
  240. /*                                                                                                                                                */$ I0 N# V* l2 o/ S+ w4 \6 Z
  241. /* Input:                                                                                                                                */+ q! s$ \! h7 ]- w% |& C0 o8 U
  242. /*                None                                                                                                                        */
    3 j9 j: B0 a  O+ O' q
  243. /*                                                                                                                                                */; U, }$ Q5 r5 u. b  O+ E* R
  244. /* Output:                                                                                                                                */# c- u7 ^9 m) y+ n% n0 _8 }
  245. /*                CE                                                                                                                                *// @$ q- y7 f8 D3 ^6 o! [
  246. /*                                                                                                                                                */0 z4 s( i, B; P9 P
  247. /************************************************************************/2 K0 Q* Y* w( |  T
  248. void CE_High() 4 |" ?" J5 c; m" T% I; m) M
  249. {; ?1 b) G9 W" E3 |; `
  250.         CE = 1;                                /* set CE high */
    9 t! T7 h7 m7 k4 w4 _2 D
  251. }% r9 K( B% z! D" {1 j

  252. , M1 w8 a$ ?, f1 H. m8 D9 }
  253. /************************************************************************/, S* F6 d5 k6 t8 [
  254. /* PROCEDURE: CE_Low                                                                                                        */( e" c" }6 A1 [# n8 i& t$ P) |
  255. /*                                                                                                                                                */
      Q+ x) `& g9 u$ W6 X
  256. /* This procedure drives the CE of the device to low.                                          */* d5 A; m8 s( l- T$ o
  257. /*                                                                                                                                                */* e# r9 Z9 o  [# M9 o
  258. /* Input:                                                                                                                                */2 t4 `( E) r: c; [
  259. /*                None                                                                                                                        */
    ! F; Q% Q: [# V7 ^8 L) o
  260. /*                                                                                                                                                *// K) M- T3 o# _
  261. /* Output:                                                                                                                                */0 l' ~8 C0 @; o# R# z
  262. /*                CE                                                                                                                                */
    5 Y1 ^# e% [9 m4 j# e7 Y& g
  263. /*                                                                                                                                                */
    , _) k/ f! |/ _5 v7 T
  264. /************************************************************************/
    ; s0 x) M7 N/ N: Q  e
  265. void CE_Low()
    % @" b, [8 q% h. H
  266. {       
    ; g3 H# O( O9 Q
  267.         CE = 0;                                /* clear CE low */
    3 P9 h0 i, _% J0 Z; _  x/ w
  268. }
    + `8 H  H' r* b; f7 s

  269. / D/ l. Y2 [4 \# M+ B: h
  270. /************************************************************************/
    8 ~( B' z+ V0 K- W
  271. /* PROCEDURE: Hold()                                                                                                        */! Z" U8 v, Y- j" t2 D* V" z
  272. /*                                                                                                                                                */
    # c2 y* y) Z1 G% @9 s9 G" m
  273. /* This procedure clears the Hold pin to low.                                                        *// _" c: ~: r3 Z9 f+ d/ c
  274. /*                                                                                                                                                */4 F4 b1 r& V; F8 J' O- Z
  275. /* Input:                                                                                                                                */5 R3 O$ ^% d6 N  q
  276. /*                None                                                                                                                        */- c( I: Y1 w8 x4 C& |
  277. /*                                                                                                                                                */+ M2 R6 w* C, ], e( F
  278. /* Output:                                                                                                                                */
    * _" W* ]. @  i; O
  279. /*                Hold                                                                                                                        */0 y8 U2 t( d& a2 C8 C" j- |" w
  280. /************************************************************************/! F3 Q" [( L+ Z! _5 I* I9 ?
  281. void Hold_Low(). m" v* v: Z4 ~' j; D+ ]
  282. {
    ! W' G6 i6 f/ c
  283.         Hold = 0;                        /* clear Hold pin */
    5 L- J& S, ]3 K& @) k) T2 E' U
  284. }
    : W+ o9 h1 A, ]1 x  y" A

  285. , r% }" I' q2 I/ Z% @
  286. /************************************************************************/* Y& g* R0 e( y6 \
  287. /* PROCEDURE: Unhold()                                                                                                        */
    & H3 C4 Q! ]0 v, ]! R
  288. /*                                                                                                                                                */# V/ U: e5 L$ D6 ]( V
  289. /* This procedure sets the Hold pin to high.                                                        */- S2 H7 B2 x( F$ D, l2 R" G
  290. /*                                                                                                                                                */
    ; P% ^6 @" [% j6 Q4 q9 J/ P: h
  291. /* Input:                                                                                                                                */% Q2 S! M) X3 D2 s! Q
  292. /*                None                                                                                                                        */. l3 }" ]9 }( n+ Z
  293. /*                                                                                                                                                */1 w3 J0 w2 k9 p0 |. P) y  F
  294. /* Output:                                                                                                                                */' U5 a7 y* F" g: k& Y& q+ I
  295. /*                Hold                                                                                                                        */0 p! ~! G6 r1 ~* L3 a
  296. /************************************************************************/5 o) x# k6 m  m! p
  297. void Unhold()
    : ^% K1 K) U) d  i( k
  298. {! C2 J9 v$ i7 j- C1 T+ j" k+ c
  299.         Hold = 1;                        /* set Hold pin */9 W% i8 w/ P; v
  300. }
    : R- B3 [: f4 v% J4 I2 B/ S9 u

  301. 2 |6 N6 d# U5 v3 }1 k$ O: C
  302. /************************************************************************/
    2 |# ~; b" ?: S+ }8 I
  303. /* PROCEDURE: WP()                                                                                                                */
    , ?+ ?2 g9 E6 s$ A) M  [
  304. /*                                                                                                                                                */$ h3 Y& s4 }# u8 B7 H) E) S% p
  305. /* This procedure clears the WP pin to low.                                                                */
    9 N' o% K9 {8 ?3 ^
  306. /*                                                                                                                                                */4 O0 ^# B0 f  U6 K- a
  307. /* Input:                                                                                                                                */9 c: g+ h8 Q" G! G5 y8 l, c! ^2 a
  308. /*                None                                                                                                                        */
    5 I/ w, M* c3 n/ ]/ i
  309. /*                                                                                                                                                */$ D& b3 b5 E8 X$ g( y- L0 c
  310. /* Output:                                                                                                                                */& O+ k5 i$ }2 }1 P
  311. /*                WP                                                                                                                                */
      J3 _9 C1 |9 K4 M# a
  312. /************************************************************************/
    0 k, p; |+ S: q& T# N  T* v! |
  313. void WP_Low()& X: G' s1 \2 _! b2 ^0 U8 l" w: t
  314. {
    ' J; |+ q/ ^! h+ L6 l
  315.         WP = 0;                                /* clear WP pin */
    / T) Z( s2 n7 I/ h. z
  316. }
    + p( Q1 G7 a- c
  317. 7 g+ P; V+ S0 R$ J! p
  318. /************************************************************************/
    ( q2 p, _; Z' Y; k& L
  319. /* PROCEDURE: UnWP()                                                                                                        */8 e; O) Y# Q* D
  320. /*                                                                                                                                                */( |. b+ b/ M2 T
  321. /* This procedure sets the WP pin to high.                                                                */
    2 d( {/ O7 `+ f5 G  q" |
  322. /*                                                                                                                                                */
    : J; J; z' j0 ^3 ]7 f: o
  323. /* Input:                                                                                                                                */! Z* l7 w# U8 p- D% ]: A
  324. /*                None                                                                                                                        */1 A% Q$ Z2 `0 P
  325. /*                                                                                                                                                */  G) W! H  D: ]4 F  w  a
  326. /* Output:                                                                                                                                */
    + M0 ?  p$ q# @) c2 A7 E
  327. /*                WP                                                                                                                                */2 `+ z  v8 ?4 _1 T" ~) g
  328. /************************************************************************/
    1 s2 F$ y* G" ^$ F8 |  w9 q
  329. void UnWP()
    ) j- \( Z5 L0 g2 p
  330. {
    ) w+ v; _5 @' R, f1 m( E. b
  331.         WP = 1;                                /* set WP pin */2 e1 x) I" b. Q$ P' W1 S
  332. }4 {$ s* J* J" N/ B4 u/ F8 Q

  333. 8 A+ Z- k# ?! G( p' G' w8 d2 ]
  334. /************************************************************************/
    4 V: Y# q( f: x4 M+ c: o
  335. /* PROCEDURE: Read_Status_Register                                                                                */7 L8 `0 C# Q$ D& D; |
  336. /*                                                                                                                                                */
    - y& v8 x( W3 T7 Y3 B, S; ]
  337. /* This procedure read the status register and returns the byte.                */7 ~- V& D$ P2 U; [2 M* v
  338. /*                                                                                                                                                */. k5 R. z% M+ B7 X3 d
  339. /* Input:                                                                                                                                */
    ' y2 v1 m( s% E7 [+ a5 B
  340. /*                None                                                                                                                        */8 [& K# {& B6 v3 ^* y* a( c, ]8 Z
  341. /*                                                                                                                                                */1 x9 P/ z( X7 _/ L4 B1 d+ Y. k9 v
  342. /* Returns:                                                                                                                                */) M$ Q. B1 X$ I8 }/ O7 ~5 N
  343. /*                byte                                                                                                                        */
    1 y$ ^7 w& i5 R' c
  344. /************************************************************************/
    9 L7 b0 a7 z1 V$ y% |/ x4 y
  345. unsigned char Read_Status_Register()
    5 c  f4 O: G* f8 i
  346. {
    - {! T. F* R# J+ R
  347.         unsigned char byte = 0;
    % X1 a! T8 @& t4 f3 v- V+ N7 K
  348.         CE_Low();                                /* enable device */! i( b" I2 Y% _( S  h) C. E, r
  349.         Send_Byte(0x05);                /* send RDSR command *// A  Q7 t3 n' U5 V* f' P# F
  350.         byte = Get_Byte();                /* receive byte */8 e# b- W) d6 W& Y
  351.         CE_High();                                /* disable device *// B: N8 @/ S0 F$ z7 p
  352.         return byte;
    + `4 N( F! V$ n* r9 z8 s3 }2 g
  353. }
    4 w; \, v! }$ R/ W/ e% r9 ~, y9 @

  354. 6 Z# h3 e4 w9 b- c- k
  355. /************************************************************************/
    4 j) b+ _2 c0 b
  356. /* PROCEDURE: EWSR                                                                                                                */
    2 Z" I6 s( K3 f) r# ?
  357. /*                                                                                                                                                */* h% s  L# o3 s: i! q# `
  358. /* This procedure Enables Write Status Register.                                                  */3 d% _! e3 Q0 i* S
  359. /*                                                                                                                                                */
    6 W$ ]3 X  i: p5 P8 l
  360. /* Input:                                                                                                                                */
    ' K  e3 M8 C8 o8 c
  361. /*                None                                                                                                                        */- P* S, Y8 U. e- x
  362. /*                                                                                                                                                */1 N4 s- S1 A9 B; X% E
  363. /* Returns:                                                                                                                                */+ j# k% X5 M# s0 Q" k
  364. /*                Nothing                                                                                                                        */4 v* N6 g2 r4 e: J; @
  365. /************************************************************************/$ V) C" `3 {1 h7 A  c7 o
  366. void EWSR()
    - t, N& A9 X9 I  x% n) w. ]
  367. {
    , i5 r0 U& u; ^7 I9 f5 H1 v. O6 z7 K
  368.         CE_Low();                                /* enable device */
    ( y, j6 ^6 I5 k  g: s* o/ y
  369.         Send_Byte(0x50);                /* enable writing to the status register */
    0 Z% h* g# `  D
  370.         CE_High();                                /* disable device */! f* ?  T% j+ h; R6 z
  371. }
    & j8 d* N% z8 Q) B8 o! p# o: d
  372. ! P: E, o- R, e4 }( T9 |( `7 V, ?
  373. /************************************************************************/
    4 Q& Z6 P( ?3 a  T
  374. /* PROCEDURE: WRSR                                                                                                                */3 L8 k# n+ ]: o( U! h* |  `9 A- y% X
  375. /*                                                                                                                                                */3 o. r! c* |0 L$ Y; u7 [
  376. /* This procedure writes a byte to the Status Register.                                        */
    - B' i1 E  o* i5 }% Z' k
  377. /*                                                                                                                                                */
    8 M2 a' r$ u; n+ y  s9 Y
  378. /* Input:                                                                                                                                */
    6 d, E/ b2 o) d6 q& V
  379. /*                byte                                                                                                                        */
    5 N. m' O4 C; [( f6 K- N/ d2 A
  380. /*                                                                                                                                                */: ?  e- k$ T( h( t. J9 }0 {
  381. /* Returns:                                                                                                                                */
    ( D  q: ^  l% O3 r" q
  382. /*                Nothing                                                                                                                        */& m' O5 _  }- N8 a4 J0 `* [
  383. /************************************************************************/4 l0 }; b8 x; {; Q! W% p/ X. W8 k
  384. void WRSR(byte): E. E8 B5 i* x" v1 j
  385. {  G- f% Y8 @1 C# [& A' {
  386.         CE_Low();                                /* enable device */
    : Y  x- W( t1 s+ p# v2 @9 S
  387.         Send_Byte(0x01);                /* select write to status register */
    5 b7 h+ y* h3 y+ b
  388.         Send_Byte(byte);                /* data that will change the status of BPx 4 N) p3 @0 O8 }4 n# k4 ]
  389.                                                                 or BPL (only bits 2,3,4,5,7 can be written) */$ b1 f( e5 j$ r. F% L% F" f
  390.         CE_High();                                /* disable the device */+ r. k3 F9 o! Q2 `4 ?
  391. }
    , Q! H5 o% K+ T

  392. 1 S. S  x! H& N7 _
  393. /************************************************************************/
    ! R  l' @+ T9 ^/ y0 ^
  394. /* PROCEDURE: WREN                                                                                                                */. U. p* T; S; x
  395. /*                                                                                                                                                */
    / O% u' g4 C: K9 s4 W
  396. /* This procedure enables the Write Enable Latch.  It can also be used         */
    3 f) ?6 W4 y7 `; K
  397. /* to Enables Write Status Register.                                                                        */6 R- p( _1 t6 C, |, p
  398. /*                                                                                                                                                */
    " _6 h; C1 o1 P$ D, v
  399. /* Input:                                                                                                                                */& P* f$ A8 ?1 C$ R( ~
  400. /*                None                                                                                                                        */
    3 t/ c9 ~. Y0 L% X+ p
  401. /*                                                                                                                                                */3 r+ I5 U" O& ~- O' J
  402. /* Returns:                                                                                                                                */
    8 S( ?  g# i  `, r+ q: Q
  403. /*                Nothing                                                                                                                        */
    % U, G4 j" t7 E* f8 x6 {
  404. /************************************************************************/1 C4 p0 J- b+ W: X% @
  405. void WREN()" f' {3 i6 @) F) u
  406. {
    ! ]4 F3 U; L) r# i! A- V8 i& T: @( X
  407.         CE_Low();                                /* enable device */+ t% A8 V4 _8 j
  408.         Send_Byte(0x06);                /* send WREN command */
    ' |, m) F# Q* Y; l, P% h
  409.         CE_High();                                /* disable device */$ T0 I' J& ~7 X
  410. }
    8 o0 O& D0 u3 H; u3 z% b
  411. . F( s$ z0 L; z
  412. /************************************************************************/
    1 q" C8 R0 h' p" P- K
  413. /* PROCEDURE: WRDI                                                                                                                */* c8 B+ [6 Y* j+ T, _
  414. /*                                                                                                                                                */9 U3 T- U' g& ~3 k+ {
  415. /* This procedure disables the Write Enable Latch.                                                */- M3 u( R. s. D
  416. /*                                                                                                                                                */2 a# q" N- u0 i4 H6 L! V
  417. /* Input:                                                                                                                                */7 Q' ^6 ~1 N. I6 M
  418. /*                None                                                                                                                        */0 ?/ t( K$ h: E! {; u2 [9 f
  419. /*                                                                                                                                                */
    ) B$ s& c$ Z3 s$ F2 O
  420. /* Returns:                                                                                                                                */! h* I+ ~; d& L4 S
  421. /*                Nothing                                                                                                                        */
    % R( ]  ~: A, T7 J$ O
  422. /************************************************************************/: s9 E5 R6 I+ O/ I5 y
  423. void WRDI()/ J; b- J+ j: A1 u- q9 @( W7 m3 U
  424. {
    ; a" T6 x0 C+ i0 m
  425.         CE_Low();                                /* enable device */( |* s3 L8 |. i& ]6 r
  426.         Send_Byte(0x04);                /* send WRDI command */& b: f+ b4 d, }8 z
  427.         CE_High();                                /* disable device */, F3 y, J3 w( G" V! H2 \: z
  428. }
    7 V; H) |* {0 [* ?7 H/ E
  429. 1 X2 o; {! b" q1 K5 L
  430. /************************************************************************/" r6 n# v4 a4 i  X% A! W+ G& d
  431. /* PROCEDURE: EBSY                                                                                                                */
    . G# J$ U* d6 }! V; ^- y7 r
  432. /*                                                                                                                                                */0 `) G: r( I# D! J5 {9 j4 |
  433. /* This procedure enable SO to output RY/BY# status during AAI                         */
      f: M4 T1 ^' ?/ J5 m# o
  434. /* programming.                                                                                                                        *// U3 O: R1 A6 g$ Y3 N8 l8 X* }5 o
  435. /*                                                                                                                                                */
    7 B2 |( n# b* n/ N
  436. /* Input:                                                                                                                                */
    ( l- x& ?# ^- ]# ^( I& p$ ]
  437. /*                None                                                                                                                        */
    & X9 m: M! \0 b
  438. /*                                                                                                                                                */
    / n8 {( M% y6 F/ o
  439. /* Returns:                                                                                                                                */
    7 T" I& [' D; f* E* s7 }* a
  440. /*                Nothing                                                                                                                        */
    ) P5 m) m" \( \
  441. /************************************************************************/
    $ ?: b5 \) Z! `/ R7 c$ M0 y' t
  442. void EBSY()
    $ G2 a$ R8 X8 G& A' V' O
  443. {- k" n7 b# [6 Z6 _) J
  444.         CE_Low();                                /* enable device */
    % K. R* B+ u" w5 F7 m/ d$ l
  445.         Send_Byte(0x70);                /* send EBSY command */9 A* {$ w2 s+ O2 |
  446.         CE_High();                                /* disable device */
    8 q$ d! j& R6 r: l: \3 S
  447. }
    & y! x2 i: ^, g4 _8 g8 t8 d, t5 ]2 C
  448. 4 u. R: X" v7 P0 f( y
  449. /************************************************************************/
    " e* X* a4 f- O! i' ~. Z% O# |
  450. /* PROCEDURE: DBSY                                                                                                                */, H" s% V8 F* m7 o7 w
  451. /*                                                                                                                                                */
    8 D' T! o5 K$ n! F& Z- G
  452. /* This procedure disable SO as output RY/BY# status signal during AAI        */
    ; B* N, g( T+ F. M. Y9 J9 D9 l6 M
  453. /* programming.                                                                                                                        */" o9 F0 s" V6 A
  454. /*                                                                                                                                                */
    2 V" L& G3 U: R' f; P8 r% ?
  455. /* Input:                                                                                                                                */: _( v5 b9 f+ J" R! h
  456. /*                None                                                                                                                        */
    # o' P* r- [5 y! p& l1 J
  457. /*                                                                                                                                                */
    / m5 }. N7 v* n0 z
  458. /* Returns:                                                                                                                                */( ], _3 M: x2 L6 n
  459. /*                Nothing                                                                                                                        */
    9 P8 o4 `$ [. t$ T4 G$ t, n
  460. /************************************************************************/
    & d- V9 q. X  @" A0 `
  461. void DBSY()! M2 ~; Q+ l" d: @3 j; g. S
  462. {* }- W+ O5 p1 n% B* U8 v# _
  463.         CE_Low();                                /* enable device */
    6 R! \0 @: l" I' _
  464.         Send_Byte(0x80);                /* send DBSY command */+ j2 L$ w- }% ~! w4 d
  465.         CE_High();                                /* disable device */
    2 D" J6 _% d- M4 Q& V& @; V# b) w4 c
  466. }
    0 _  b. ^) u  H* [
  467. . H# x4 j- ^/ X
  468. /************************************************************************/
    ) \4 ~  N7 h% q* g
  469. /* PROCEDURE: Read_ID                                                                                                        */- s/ e! C: J0 `' }0 L7 _) V
  470. /*                                                                                                                                                */
    - _$ o' F& [4 C) Y" r+ Y- W( h; N
  471. /* This procedure Reads the manufacturer's ID and device ID.  It will         */
    ( S4 u8 D) z  v5 L; D' z
  472. /* use 90h or ABh as the command to read the ID (90h in this sample).   */& y6 D% L: {) m2 D' O7 p7 Z# U8 W, q
  473. /* It is up to the user to give the last byte ID_addr to determine      */5 f8 a3 [$ [( L# A- }
  474. /* whether the device outputs manufacturer's ID first, or device ID         */" r" ]& k/ M2 H; o( L
  475. /* first.  Please see the product datasheet for details.  Returns ID in */7 X( z) J8 i% H" s5 ~! {
  476. /* variable byte.                                                                                                                */+ h$ g4 a* f. |, v7 q9 d/ c" j
  477. /*                                                                                                                                                */+ N7 G) I" e$ n% B3 }
  478. /* Input:                                                                                                                                */3 |4 r3 O1 u# e. A& U" W
  479. /*                ID_addr                                                                                                                        */% V" e3 U: J  z' L: Y! q. e, x  h. Q
  480. /*                                                                                                                                                */
    5 H! _. N4 t5 T3 T$ q- g8 x
  481. /* Returns:                                                                                                                                */8 g8 `- g+ {4 [' \* o* H+ @
  482. /*                byte:        ID1(Manufacture's ID = BFh or Device ID = 8Eh)                        */
    3 V, d  V3 @( [3 {* C, v7 h5 ?
  483. /*                                                                                                                                                */
    ; o4 ]$ W0 m! b! f" j( `, W- ?
  484. /************************************************************************/  @" g& I8 q$ ~. v
  485. unsigned char Read_ID(ID_addr)9 t6 b7 ^" C. o* w- K: x0 n% V
  486. {0 H$ v, w5 D9 k! x, g
  487.         unsigned char byte;8 h3 m0 X0 n% M
  488.         CE_Low();                                /* enable device */. L' E' B8 ]4 g, m% c5 P: D
  489.         Send_Byte(0x90);                /* send read ID command (90h or ABh) */
      f3 [5 J: J8 m5 N/ r* a
  490.     Send_Byte(0x00);                /* send address */
    6 k0 f, ], G- `- r# L
  491.         Send_Byte(0x00);                /* send address */
    / o5 ^' E$ ?- U, Q7 c( z# ^# @8 k
  492.         Send_Byte(ID_addr);                /* send address - either 00H or 01H */" W; i$ d9 Q5 a
  493.         byte = Get_Byte();                /* receive byte */
    * ]& u1 Z$ E  b2 S1 i& F
  494.         CE_High();                                /* disable device */
    $ `9 Q6 p4 U3 `; W/ q/ {
  495.         return byte;$ q: Q8 Z$ s' x: W( A' a
  496. }
    ( N& I2 ~: ]* n2 g7 P  ^9 m
  497. ' ~$ R* n7 x8 [  L
  498. /************************************************************************/
    0 n: ]! V2 T3 [* I4 y/ o
  499. /* PROCEDURE: Jedec_ID_Read                                                                                                */# Y/ E! ?9 Y  |' l
  500. /*                                                                                                                                                */
    3 d' j" v, n/ G0 ]8 {2 f( I
  501. /* This procedure Reads the manufacturer's ID (BFh), memory type (25h)  */% ~7 k; z! F( f7 ]! X
  502. /* and device ID (8Eh).  It will use 9Fh as the JEDEC ID command.            */
    ! C- g. M! ^& m! T$ y
  503. /* Please see the product datasheet for details.                                                  */+ y: d0 u3 [: d: d# c/ l
  504. /*                                                                                                                                                */
    9 X# a; _* o& J
  505. /* Input:                                                                                                                                */0 f2 n8 X( S& [0 v
  506. /*                None                                                                                                                        */3 H& O9 r5 k; h6 I+ c
  507. /*                                                                                                                                                */
    - i4 F7 ^: `3 ]7 B
  508. /* Returns:                                                                                                                                */; _5 j: o% z( r+ [  v  i
  509. /*                IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h),                        */2 g% ]1 z. g0 P! Q* G
  510. /*                 and Device ID (8Eh)                                                                                        */
    # C* l0 {( V/ G$ A& y, F
  511. /*                                                                                                                                                */& C) e% }! i( ~
  512. /************************************************************************/0 B" a! v; S8 I% s6 s6 F% Z/ e
  513. unsigned long Jedec_ID_Read() . c4 t7 U" s. w
  514. {
    7 n' m# |# [4 j& n
  515.         unsigned long temp;5 w5 t9 F3 b4 G# }% B2 e0 B
  516.        
    ) O: s; o% h& a
  517.         temp = 0;
    $ z/ i+ J7 a! h
  518. : h* @6 d" x2 D9 r& L+ p0 Y
  519.         CE_Low();                                        /* enable device */# x# _- x1 D- S/ ?! ~* R* ^
  520.         Send_Byte(0x9F);                        /* send JEDEC ID command (9Fh) */
    7 ?0 T; W! Q# f" g5 o% w; k
  521.     temp = (temp | Get_Byte()) << 8;        /* receive byte */; \5 f0 k( f5 T
  522.         temp = (temp | Get_Byte()) << 8;       
    " E+ x4 R! K% }+ y7 F2 t8 b
  523.         temp = (temp | Get_Byte());                 /* temp value = 0xBF258E */
    * ], z; D6 f( j: X! B5 c
  524.         CE_High();                                                        /* disable device */- ^3 n# R0 |+ X( O3 e" X

  525. $ p' T' k" {8 @
  526.         return temp;
    " a; R7 Y. t, t2 P# P5 c+ `
  527. }
    ! K3 l, Y8 r: o( {& y

  528. * q! m, G: u% g2 i" C" W
  529. /************************************************************************/
    2 n3 k$ H2 b" P& I- n2 _
  530. /* PROCEDURE:        Read                                                                                                        */$ g: T0 ~) M- I6 M. [) R
  531. /*                                                                                                                                                */               
    " C# o- ]% \/ ]9 e/ y+ Q! D3 f
  532. /* This procedure reads one address of the device.  It will return the         */6 U% A/ z$ _' P( U/ I
  533. /* byte read in variable byte.                                                                                        */8 B7 U4 ]. x' B; g/ [
  534. /*                                                                                                                                                */
    8 R; t% F9 |  g- {
  535. /*                                                                                                                                                */) F7 C  E3 Q' y, H, |
  536. /*                                                                                                                                                */' L) q) b2 r3 J- d  i
  537. /* Input:                                                                                                                                */5 _9 M. ^, U# c. _
  538. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    , @# `9 n, m7 a' l  W$ ~* e
  539. /*                                                                                                                                      */
    + U4 d: y& Z- \6 I9 ^) n0 s
  540. /*                                                                                                                                                */
    ( }( D& [. I0 U, S5 _$ f% B
  541. /* Returns:                                                                                                                                */& l/ i0 _9 E' w& W
  542. /*                byte                                                                                                                        */
    / \  n7 A! |+ _1 j  M% o" g8 N+ P" C! H
  543. /*                                                                                                                                                */
    " a, r* d& h; M; S# l& G8 j
  544. /************************************************************************/" F' B1 F1 g% p6 K! f  p5 G# s% J
  545. unsigned char Read(unsigned long Dst)
    4 u' a7 f: W4 @# B
  546. {) g+ Q  Q4 o+ ]
  547.         unsigned char byte = 0;       
    ( J$ H- u3 n: [; F- H
  548. 9 m1 O+ H8 k" c0 Y+ a3 U7 G
  549.         CE_Low();                                /* enable device */6 ]9 a3 ?4 w  {. N! t2 @
  550.         Send_Byte(0x03);                 /* read command */+ R2 M" ]$ x* c
  551.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    0 H* v2 Q- g" ]$ M& ?7 K0 W5 {
  552.         Send_Byte(((Dst & 0xFFFF) >> 8));
    - r& {. b$ L* f" E0 _
  553.         Send_Byte(Dst & 0xFF);9 j% L8 y; ~0 X4 k  ~8 x" j) ]
  554.         byte = Get_Byte();6 \5 X" V# s9 n" a
  555.         CE_High();                                /* disable device */
    5 |7 B2 E5 `4 O) l7 E$ \2 H0 C
  556.         return byte;                        /* return one byte read */
    6 t$ m6 i; s3 v
  557. }5 J& j8 M9 b: K& p

  558. 4 ]  G6 _" ]9 T; L1 j  N& g! {
  559. /************************************************************************/$ t3 u. W6 Y, a1 Z" j' }. }1 @, Y
  560. /* PROCEDURE:        Read_Cont                                                                                                */
    , F$ C  ^( Z3 _
  561. /*                                                                                                                                                */                $ c- P: h3 }6 p* d
  562. /* This procedure reads multiple addresses of the device and stores                */
    " P; p; }) I& O+ l
  563. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/5 H# Q- c) w- J
  564. /*                                                                                                                                                */
    3 A. i% V# Y9 ]
  565. /* Input:                                                                                                                                */0 ^, p2 ]" v; F! z2 s3 a( H5 W# k3 }
  566. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    % g9 f/ M- t8 T
  567. /*      no_bytes        Number of bytes to read        (max = 128)                                        */! s2 R% J3 v+ K1 J9 z3 n  W
  568. /*                                                                                                                                                */
      g* q0 n: W/ [# H4 m0 K& |4 C
  569. /* Returns:                                                                                                                                */3 E/ I$ Q. Z) D# |' m
  570. /*                Nothing                                                                                                                        */
      Z7 T+ M5 f( R) \8 @: A+ D. D7 z
  571. /*                                                                                                                                                */
    * d* r) s+ z. z8 [$ i0 u
  572. /************************************************************************/# |) M$ T  B. x, S# p+ j3 m9 k3 {
  573. void Read_Cont(unsigned long Dst, unsigned long no_bytes)
    0 u/ z8 v: F! _
  574. {
    1 v) l, B, P" t2 p7 j6 `
  575.         unsigned long i = 0;6 H& {; B  z9 _9 R, N
  576.         CE_Low();                                        /* enable device */9 c& q  E# q  x' e2 _
  577.         Send_Byte(0x03);                         /* read command */" f% N8 S6 H3 U
  578.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    $ {* c: O# {' F" V
  579.         Send_Byte(((Dst & 0xFFFF) >> 8));+ L) s* Q7 ~1 i( [; o3 q
  580.         Send_Byte(Dst & 0xFF);* |  p* x5 E' N
  581.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    8 b/ ^& [. E1 f8 M2 G' {
  582.         {7 A6 A, L' ~; B& I+ F4 l& ^3 B
  583.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */; K6 U/ y7 e% h% g5 W, ?, y! c
  584.         }$ n+ K: I* z8 U( M/ v
  585.         CE_High();                                        /* disable device */
    - z1 J+ X$ e8 e- g% }
  586. ) y+ T) ]7 ]8 t& i  J2 j: q' ^$ K& y
  587. }
    : u* [) m+ ?3 S) W1 m1 V: w! b

  588.   N. G5 f; P, J/ [6 Y& E$ d* Y
  589. /************************************************************************/
    : `8 B) z$ X6 d* K9 z1 k
  590. /* PROCEDURE:        HighSpeed_Read                                                                                        */$ x1 a$ Z! E: B! w
  591. /*                                                                                                                                                */                % f9 F- o8 ~2 ~# r5 `- V0 [
  592. /* This procedure reads one address of the device.  It will return the         *// f. f; d) j6 a4 T. D6 ~
  593. /* byte read in variable byte.                                                                                        */5 q2 \. n- ~" U& f
  594. /*                                                                                                                                                */4 f8 B4 M, t4 o
  595. /*                                                                                                                                                */
    4 E2 F$ U- I+ S  M5 V) t
  596. /*                                                                                                                                                */
    + G/ _( K) [/ x0 P. M
  597. /* Input:                                                                                                                                */
    & r& e& m( d5 M" h% ]
  598. /*                Dst:        Destination Address 000000H - 0FFFFFH                                        */
    & [" j( H" O7 R# U) W1 r
  599. /*                                                                                                                                      */. t7 i6 t- l4 H' ^2 S8 T* R
  600. /*                                                                                                                                                */
      f! q5 D2 s$ [9 A
  601. /* Returns:                                                                                                                                */7 A! T" X4 \, W+ V5 y7 E
  602. /*                byte                                                                                                                        */# R5 z1 A2 m1 ], X( {; x
  603. /*                                                                                                                                                */
    , a3 s$ z: a: [3 Y# q
  604. /************************************************************************/3 h3 X8 b3 J" _) E) N, {
  605. unsigned char HighSpeed_Read(unsigned long Dst) 2 q/ O* v- Y* W$ u" y
  606. {
    , u2 [- F- o, l; y5 K4 H6 w) ]
  607.         unsigned char byte = 0;       
    - [  Q' \0 |' p: {1 M
  608. 8 d, V4 S2 y, Z1 g# b5 g
  609.         CE_Low();                                /* enable device */9 ?5 P) H8 F, J/ f7 f! a
  610.         Send_Byte(0x0B);                 /* read command */
    ; a3 Y8 F' ^, Z5 @8 {: V
  611.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    8 f; t5 n' e- j3 U
  612.         Send_Byte(((Dst & 0xFFFF) >> 8));
    : c. A/ s* J: s0 O
  613.         Send_Byte(Dst & 0xFF);2 W; m. j( A+ @; M* X
  614.         Send_Byte(0xFF);                /*dummy byte*/+ h# E5 Z; X+ c
  615.         byte = Get_Byte();
    : `0 k, e6 I1 ~6 ^3 Z" S
  616.         CE_High();                                /* disable device */
    ! b  {4 M5 R) L$ m9 O# A
  617.         return byte;                        /* return one byte read */
    , o7 a* c" [) @2 n  K! C+ Y
  618. }
    / `6 B$ ]+ t5 \2 x" a1 B
  619. ) H6 s& J3 i. l! j* |5 h/ z
  620. /************************************************************************/6 {( J' Z$ F6 I3 V
  621. /* PROCEDURE:        HighSpeed_Read_Cont                                                                                */  q/ N3 W4 [9 k$ M
  622. /*                                                                                                                                                */               
    . O- p2 N# C2 w& i& I1 `+ t
  623. /* This procedure reads multiple addresses of the device and stores                */" \( ]  E2 Y7 Q# t7 ]
  624. /* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/4 I' c" U7 Y" r. e  J
  625. /*                                                                                                                                                */
    $ i* k9 n1 r0 @+ y* v5 e6 o6 j
  626. /* Input:                                                                                                                                */! m9 P  A: U% u& ^7 S: c
  627. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    $ W' a; R( Q! J7 b8 [. N  D
  628. /*      no_bytes        Number of bytes to read        (max = 128)                                        */3 }; k! g$ a4 ~% I
  629. /*                                                                                                                                                */
    ; F( {4 H- l0 y) R! X
  630. /* Returns:                                                                                                                                */$ ]: |, M: \. `, P" u% X
  631. /*                Nothing                                                                                                                        */
    4 D( _7 i- W0 P: d; y$ U' \
  632. /*                                                                                                                                                */6 X  ?2 i, S" A8 E. i6 ?' `% h
  633. /************************************************************************/1 _0 e4 T; {1 u! {8 {, o$ Z3 W
  634. void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)" Z; v5 F, {* c2 N4 k
  635. {
    : c( i+ O' ]: b$ p7 z1 Z. ^
  636.         unsigned long i = 0;$ W2 h1 d+ \0 ]' ~
  637.         CE_Low();                                        /* enable device */; n3 i5 Q1 m$ q, T' @
  638.         Send_Byte(0x0B);                         /* read command */. ~5 P+ |) G# v7 u3 e
  639.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */+ P: }3 H! ^# R3 g
  640.         Send_Byte(((Dst & 0xFFFF) >> 8));
    ; B! N5 f- G$ d' ^, Q7 E$ A$ V
  641.         Send_Byte(Dst & 0xFF);) h' y, C/ m* C2 ^% t; s& |8 x; y' u
  642.         Send_Byte(0xFF);                        /*dummy byte*/
    , V0 L$ b  [; I  ]+ }- f& {
  643.         for (i = 0; i < no_bytes; i++)                /* read until no_bytes is reached */
    3 r, v4 F8 ^8 q2 c+ Z6 G1 R
  644.         {
    0 B4 D8 b; J: V: t4 w9 |
  645.                 upper_128[i] = Get_Byte();        /* receive byte and store at address 80H - FFH */
    ( L# E7 i( w( U1 t
  646.         }
    , K& V' r, x) X# d
  647.         CE_High();                                /* disable device */' {) S0 C7 ?* k2 [. U
  648. }0 L% C( i* `" V& e
  649. 2 q8 e4 {8 \4 o+ e7 C+ |
  650. /************************************************************************/7 B: P1 \- l! J' Y( `* {" c
  651. /* PROCEDURE:        Byte_Program                                                                                        */! r- Z% ~9 G$ n* @) `% k. e3 C* h
  652. /*                                                                                                                                                */1 j: v* c0 e! H) g' `% f
  653. /* This procedure programs one address of the device.                                        */
    # Y6 z6 O( z% x1 A3 X  g
  654. /* Assumption:  Address being programmed is already erased and is NOT        */5 G- `# }1 b/ u9 M& P, F- M- p
  655. /* block protected.                                                                                                                */; r  F, q; g/ D' D
  656. /*                                                                                                                                                */+ b$ C; P7 n* H" r
  657. /*                                                                                                                                                *// D6 m: B* X' U
  658. /*                                                                                                                                                */
    . ]7 U9 I0 d  d1 v' k! P7 Z* {6 M
  659. /* Input:                                                                                                                                */9 H& K$ T6 Q. ^& @; h
  660. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */( L$ @; Q; z) R' n3 p/ J
  661. /*                byte:                byte to be programmed                                                                */5 @/ y, |' ^1 y9 K! \( R
  662. /*                                                                                                                                      */6 D3 J  v2 v9 v6 l/ `/ G" a4 }: G
  663. /*                                                                                                                                                *// z# \" p4 [8 T' e1 u
  664. /* Returns:                                                                                                                                */  ?; C7 U. \# @& k- Z0 V& }
  665. /*                Nothing                                                                                                                        */
    9 z  \5 ?# {3 U9 t+ H5 ~( j
  666. /*                                                                                                                                                */$ E9 l& u8 O- d: G
  667. /************************************************************************/
    6 u$ O! t) v/ }/ y8 i5 O
  668. void Byte_Program(unsigned long Dst, unsigned char byte)1 ?( h5 g- Z$ G; }% U9 D( v2 f
  669. {, ]" V! j- a9 d- q% U& U. B
  670.         CE_Low();                                        /* enable device */$ B7 \1 K/ T4 {2 M- }
  671.         Send_Byte(0x02);                         /* send Byte Program command */
    6 M4 n1 l8 v) B; y
  672.         Send_Byte(((Dst & 0xFFFFFF) >> 16));        /* send 3 address bytes */
    0 q' G4 s- D! Y
  673.         Send_Byte(((Dst & 0xFFFF) >> 8));0 @8 @* U* T; B( G! M% j% ^
  674.         Send_Byte(Dst & 0xFF);
    2 {6 C3 Y' r: b+ u1 V
  675.         Send_Byte(byte);                        /* send byte to be programmed */
    $ k4 q! n2 @0 o" [
  676.         CE_High();                                        /* disable device */
    . x6 g  d) p0 }2 k! s% p+ H  {- k
  677. }  \5 A1 \/ l' t+ l: \( D$ U

  678.   I5 d0 h5 ^: m# T5 H* X
  679. /************************************************************************/
    7 y  |+ f, c: O: o
  680. /* PROCEDURE:        Auto_Add_IncA                                                                                        */
      m3 u; j4 Z0 q6 L! e" S
  681. /*                                                                                                                                                */; a& y8 h( _; Q
  682. /* This procedure programs consecutive addresses of 2 bytes of data into*/5 K4 p9 h/ R  U: K- p
  683. /* the device:  1st data byte will be programmed into the initial                 */
    ! }. F  L/ Q% Y9 l4 `
  684. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */  ], K6 L! R2 a
  685. /* programmed into initial address [A23-A1] and with A0  = 1.  This          */# D& c; E1 A$ x% k8 g& R
  686. /* is used to to start the AAI process.  It should be followed by                 */
    9 A: p/ s* R3 f4 p2 I5 O4 {% M
  687. /* Auto_Add_IncB.                                                                                                                */
    ( V7 B9 j+ w2 J+ q
  688. /* Assumption:  Address being programmed is already erased and is NOT        */
    ' o! R! ~( t9 G3 h# O4 c
  689. /*                                block protected.                                                                                */
    1 E* R7 T) }1 ^  q+ }
  690. /*                                                                                                                                                */
    ( y* S/ |( h. Y
  691. /*                                                                                                                                                */
    + Y8 K7 ~: ]) g) U; f0 Y% J
  692. /* Note: Only RDSR command can be executed once in AAI mode with SO          */
    $ e/ y. R9 Z+ F2 ~2 R+ |
  693. /*          disable to output RY/BY# status.  Use WRDI to exit AAI mode                 */
    " Y) p# J! o% N% F% |/ K- h
  694. /*         unless AAI is programming the last address or last address of                */
    3 Q! W/ @9 a4 n+ V
  695. /*          unprotected block, which automatically exits AAI mode.                                */, o6 H$ e# {4 ^# q/ O
  696. /*                                                                                                                                                */; j9 H# G; K9 y5 o- t
  697. /* Input:                                                                                                                                */
      v$ }. |% w$ o6 p
  698. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    # W! n3 o9 o2 ^$ d4 ^
  699. /*                byte1:                1st byte to be programmed                                                        */
    ! g0 W2 B' }( V+ z/ q1 R$ ]
  700. /*      byte1:                2nd byte to be programmed                                                        */" b6 z. N3 f2 }$ k: N5 A' }: S5 M
  701. /*                                                                                                                                                */
    & O+ N- f& {4 {, N8 |: t# l/ y  G
  702. /* Returns:                                                                                                                                */
    : d; D" v# e. x6 G
  703. /*                Nothing                                                                                                                        */
    2 O. p) Z# u' m
  704. /*                                                                                                                                                */9 y; [( g- t  t/ m' |* Q% T2 W- N
  705. /************************************************************************/
    5 r3 b: F# ]) n. |: c8 n: `
  706. void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)3 }3 U% V. u# k0 y7 |) @
  707. {
    7 L) t; h( J( @" M6 a/ ?
  708.         CE_Low();                                        /* enable device */
    # U8 Z' X: s; H$ x9 c- [  W
  709.         Send_Byte(0xAD);                        /* send AAI command */
    ! g2 F1 u, T/ t8 ]' }$ \2 a, B5 a
  710.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */$ P7 L+ p3 @$ P- J
  711.         Send_Byte(((Dst & 0xFFFF) >> 8));
    6 ~7 f6 ^5 g8 {: |8 [# X
  712.         Send_Byte(Dst & 0xFF);
    - ~1 X/ y; T9 n
  713.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        $ \5 w+ a+ O' G) p! e. }! N6 ]
  714.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */) V' H' T" ?; l; r
  715.         CE_High();                                        /* disable device */4 t  A9 o& a/ ?( T
  716. }
    5 }. J: r0 N) V& v! S* P! s
  717. : U  P7 E  d; Z! a6 n# N. D
  718. /************************************************************************/# e% M4 J2 |. X$ d6 U, I
  719. /* PROCEDURE:        Auto_Add_IncB                                                                                        */
    0 Z; v2 Y1 N# {( Z  M
  720. /*                                                                                                                                                */* Y) f3 d/ U4 v; Y
  721. /* This procedure programs consecutive addresses of 2 bytes of data into*/' z+ B  P  O6 I- Y
  722. /* the device:  1st data byte will be programmed into the initial                 */0 o" P' z  J. @& C0 i2 g
  723. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be be                 */
    ( b0 ?# q! {( v" f: C! Q
  724. /* programmed into initial address [A23-A1] and with A0  = 1.    This          */. |- J2 s3 _, Y# h4 R) H
  725. /* is used after Auto_Address_IncA.                                                                                */' O3 C& v* c* U7 ?. \
  726. /* Assumption:  Address being programmed is already erased and is NOT        */
    4 k9 f; U  Y. q
  727. /*                                block protected.                                                                                */
    5 r( ^3 |3 u/ S0 P' b
  728. /*                                                                                                                                                */
    $ B" H$ T9 \% P) H) E- F0 i
  729. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */  J6 s3 M7 k6 T- G. i
  730. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    3 w- H/ I6 I0 s, r; h0 }
  731. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */) C, o9 Y# f9 k3 s
  732. /*          to exit AAI mode unless AAI is programming the last address or                */5 ?6 r" Y: O/ X3 x
  733. /*         last address of unprotected block, which automatically exits                 */& a+ K7 l! M# y2 d
  734. /*         AAI mode.                                                                                                                        */2 X% y( ~' _$ N2 p9 X3 W/ j/ P
  735. /*                                                                                                                                                */
    * i4 L) K1 \: p3 X
  736. /* Input:                                                                                                                                */
    / v  `' r! q" C, I
  737. /*                                                                                                                                                */- M5 r* b& }3 k$ S/ k7 y3 ^
  738. /*                byte1:                1st byte to be programmed                                                        */
    ! t$ }$ F9 Y6 F. Z2 ?
  739. /*                byte2:                2nd byte to be programmed                                                        */8 q! a5 K1 C! j* o& ]
  740. /*                                                                                                                                      */
    8 O* H; e7 c+ G% B; I" E
  741. /*                                                                                                                                                */* {+ ~9 U$ j% ~: m: d
  742. /* Returns:                                                                                                                                */
    3 {/ N& X. Q: ~8 M$ Y
  743. /*                Nothing                                                                                                                        */
      E/ C: e; Q9 H# X2 }" R3 M
  744. /*                                                                                                                                                */
    8 O% J* A" v0 o% R/ H% `9 p3 v' N
  745. /************************************************************************/
    8 ~2 I5 t6 c" b+ {& F8 p
  746. void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
    % C& T: O: v. ?* O
  747. {
    : q, U4 r! J" Z  G
  748.         CE_Low();                                        /* enable device */
    ( \* O) H  w* Y7 y
  749.         Send_Byte(0xAD);                        /* send AAI command */
    - k0 Y3 n. N( h
  750.         Send_Byte(byte1);                        /* send 1st byte to be programmed */( ^, X  h+ T3 L2 T' S+ L  o
  751.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    ; H% Y0 n- u# `3 ]
  752.         CE_High();                                        /* disable device */
    : a8 v; A/ [$ Q0 l
  753. }
    ; M8 n) |1 f, r, K

  754. - H, c$ `$ G( F
  755. /************************************************************************/% s: f" e! v8 F5 n3 j
  756. /* PROCEDURE:        Auto_Add_IncA_EBSY                                                                                */
    7 k0 U' m1 p7 t
  757. /*                                                                                                                                                */0 K7 A3 q: C0 x9 l
  758. /* This procedure is the same as procedure Auto_Add_IncA except that it */
    ' t* @" l" z( z4 b+ e
  759. /* uses EBSY and Poll_SO functions to check for RY/BY. It programs                 */( A9 b5 i0 A& r+ n2 F
  760. /* consecutive addresses of the device.  The 1st data byte will be                 */
    , H8 s" w& ^6 n8 a# ~+ m
  761. /* programmed into the initial address [A23-A1] and with A0 = 0.  The         */3 k8 A( g7 f3 |# w5 V, j# |3 ^
  762. /* 2nd data byte will be programmed into initial address [A23-A1] and         */$ N$ [% o9 X2 N7 Q+ K
  763. /* with A0  = 1.  This is used to to start the AAI process.  It should  */" g/ j1 p7 w0 I& T6 ~; F6 ]; `3 z
  764. /* be followed by Auto_Add_IncB_EBSY.                                                                        */0 v" Z  L9 Y0 s1 S
  765. /* Assumption:  Address being programmed is already erased and is NOT        */) o! F- ?! Y3 C$ P, M  D: |: \2 ?( Q
  766. /*                                block protected.                                                                                */
    5 `5 F* ~. y1 `8 H: \2 m4 b: q
  767. /*                                                                                                                                                */$ q& {/ \  z6 v2 w- W4 v
  768. /*                                                                                                                                                */
    4 m( W2 J+ k, D, J
  769. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */' S8 r3 v6 D5 D% `( s% }
  770. /*         with SO enabled as RY/BY# status.  When the device is busy                 */
    $ C* i; i+ H4 ]
  771. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        *// `$ f& k% [/ Z
  772. /*          to exit AAI mode unless AAI is programming the last address or                */
    ) X8 A6 I3 {! j  J$ h
  773. /*         last address of unprotected block, which automatically exits                 */
    " ^1 O5 L. t! F( a
  774. /*         AAI mode.                                                                                                                        */
    7 l+ y) m7 \, R
  775. /*                                                                                                                                                */2 U0 |. J& b6 O9 }; b2 M
  776. /* Input:                                                                                                                                */% l1 C* D! V! M# ?
  777. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & `- X6 W' P8 X% ~; `. H5 M& s
  778. /*                byte1:                1st byte to be programmed                                                        */
    - N2 ^8 f1 Y6 H1 z4 `! q
  779. /*      byte1:                2nd byte to be programmed                                                        */( f7 E! I/ V2 M, F4 C2 A8 X" \
  780. /*                                                                                                                                                */- i3 R5 h9 L6 h& F6 v+ {1 z
  781. /* Returns:                                                                                                                                */
    . F7 o) ~, j; X1 N2 i" B$ D
  782. /*                Nothing                                                                                                                        */% ]5 S: F! F* a3 F. D5 @$ X
  783. /*                                                                                                                                                */& d! S9 I* R* p1 z  u
  784. /************************************************************************/' s1 U) V: _' q
  785. void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
    8 J# X- v+ R+ U
  786. {
    # \6 k. O+ t- ?% E
  787.         EBSY();                                                /* enable RY/BY# status for SO in AAI */        9 Z9 z6 S& m* M

  788. . r( r! C- B2 }" g6 _1 [7 l9 D
  789.         CE_Low();                                        /* enable device */; {+ M7 H! ^& \- o0 K% M8 W! G
  790.         Send_Byte(0xAD);                        /* send AAI command */
    . |4 R6 D+ t- F9 c% Z8 L5 g' Q; A5 U
  791.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes *// Y& [7 ^" a$ }
  792.         Send_Byte(((Dst & 0xFFFF) >> 8));
    : y8 s3 E* T- f
  793.         Send_Byte(Dst & 0xFF);
    8 {/ [# s) U7 k
  794.         Send_Byte(byte1);                        /* send 1st byte to be programmed */        / U  ?% U3 h0 k4 ?1 ?
  795.         Send_Byte(byte2);                        /* send 2nd byte to be programmed */
    , `9 D0 t( i3 U3 b. w5 O6 H1 `
  796.         CE_High();                                        /* disable device */
    5 j5 v, W% t4 I5 ?
  797.        
    ' j! T: C1 ^1 E4 f# y# a, l
  798.         Poll_SO();                                        /* polls RY/BY# using SO line */# _4 ?, }6 r# ]; P& ~

  799. : a7 @) {2 d6 m' F" ?! k5 m* q
  800. }8 e4 G  W  I3 g8 |

  801. " p) M: ~$ X5 m0 V/ T
  802. /************************************************************************/
    0 A0 `. w) P4 C2 ?2 H, {1 X
  803. /* PROCEDURE:        Auto_Add_IncB_EBSY                                                                                */
      x4 F6 S) @7 b7 N' @8 G
  804. /*                                                                                                                                                */5 ~1 k: q4 V5 f& g
  805. /* This procedure is the same as Auto_Add_IncB except that it uses                 */
    ; \, P+ p2 {% v7 }8 g0 N, g  e
  806. /* Poll_SO to poll for RY/BY#.  It demonstrate on how to use DBSY after        */
    ! a  N+ @4 X. O  N9 n
  807. /* AAI programmming is completed.  It programs consecutive addresses of */6 s! ?  B8 r1 e+ p' h
  808. /* the device.  The 1st data byte will be programmed into the initial   */) o, D8 |7 v3 P) p$ Q; C
  809. /* address [A23-A1] and with A0 = 0.  The 2nd data byte will be                        */. y9 D. Y! `$ j3 D% V# ^
  810. /* programmed into initial address [A23-A1] and with A0  = 1.  This is         */7 x1 U/ r5 ?/ f
  811. /* used after Auto_Address_IncA.                                                                                */: F2 ^2 H$ j: ~. w$ O; E0 o
  812. /* Assumption:  Address being programmed is already erased and is NOT        */
    ! p' ^( v  I6 W9 t8 N( D6 i  J
  813. /*                                block protected.                                                                                */
    ' s9 B0 n0 J3 N* v* @5 {
  814. /*                                                                                                                                                */  D6 `$ U' B" Y% p
  815. /* Note: Only WRDI and AAI command can be executed once in AAI mode         */
    ' c0 I  s9 W5 ?* F
  816. /*         with SO enabled as RY/BY# status.  When the device is busy,                 */
    7 `" n0 I+ f" \* g! ^0 S
  817. /*         asserting CE# will output the status of RY/BY# on SO.  Use WRDI        */
    : [) W2 L& h" E
  818. /*          to exit AAI mode unless AAI is programming the last address or                */
    ( X# b7 W* |# k
  819. /*         last address of unprotected block, which automatically exits                 */9 p. S7 P3 O) r& T; Y- u# h
  820. /*         AAI mode.                                                                                                                        */* ^* h% Z' g# ^
  821. /*                                                                                                                                                */4 e% E/ e# O% |
  822. /* Input:                                                                                                                                */
    ! K1 h4 Q) ~5 p1 A; N
  823. /*                                                                                                                                                */) N- R. z$ X6 h. Z5 @
  824. /*                byte1:                1st byte to be programmed                                                        */- W, V. P& `7 s( v- E
  825. /*                byte2:                2nd byte to be programmed                                                        */
    # m& _7 j7 s( V0 `% N/ Q" O
  826. /*                                                                                                                                      */
    - t* u7 J6 \# d" L
  827. /*                                                                                                                                                */5 H& h: f. o4 m/ M+ w
  828. /* Returns:                                                                                                                                */, S& O9 E6 o0 G4 m( k% n
  829. /*                Nothing                                                                                                                        */, k( k7 j3 a7 B' A. w
  830. /*                                                                                                                                                */: n  {" A% `/ c' {7 R
  831. /************************************************************************/
    3 h( M& M8 k: }$ E. h5 `- i
  832. void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)% X# ~! h$ G, p" {8 y
  833. {* a. q$ B, V7 y' J+ \4 f
  834.         CE_Low();                                /* enable device */2 E8 g7 J0 W) k8 Q0 ]
  835.         Send_Byte(0xAD);                /* send AAI command */! Z# `2 l1 U0 v6 R
  836.         Send_Byte(byte1);                /* send 1st byte to be programmed */
    . ]  k( P- o$ E. {3 u! {" ?  Z
  837.         Send_Byte(byte2);                /* send 2nd byte to be programmed */
    ' K- u- B; h% x& O7 m
  838.         CE_High();                                /* disable device */
    3 ~$ B) A2 N3 j

  839. 3 s8 h8 K7 T# o* Q; h
  840.         Poll_SO();                                /* polls RY/BY# using SO line */0 H8 z" W8 B  v  g( X$ b3 O
  841. 9 n5 i( u& a: }* j3 h
  842.         WRDI();                                 /* Exit AAI before executing DBSY */
    # H' p. \3 \/ e! Y
  843.         DBSY();                                        /* disable SO as RY/BY# output if in AAI */3 @" k' Z$ r3 H0 K$ m
  844. }
    5 \1 j" v9 i7 @0 G/ V( |  d

  845.   x+ @1 U) \1 a) _. R. _( d
  846. /************************************************************************/
    + P! _5 ~, [- [! q0 J' y) d
  847. /* PROCEDURE: Chip_Erase                                                                                                */" i/ d) w+ Z2 {# i0 d
  848. /*                                                                                                                                                */  l# ~! T7 ?$ [2 M$ o
  849. /* This procedure erases the entire Chip.                                                                */
    2 G' Z9 \9 A: X  i+ ^
  850. /*                                                                                                                                                */
    " u- p3 E2 S: ?5 M( \
  851. /* Input:                                                                                                                                */; b$ j* i* H1 V
  852. /*                None                                                                                                                        */
    9 B) T" L! Y: O# H- w1 X; I! a! U
  853. /*                                                                                                                                                */' c) o  c& R$ |" g
  854. /* Returns:                                                                                                                                */- |$ g2 U$ `) ?' o3 s  a+ {
  855. /*                Nothing                                                                                                                        */6 K, U) O1 `5 g( C# [+ V- @* o
  856. /************************************************************************/
    * t. _$ `" ~; b! |
  857. void Chip_Erase()
    % c2 R5 q7 l1 K& D) ^0 Y8 N. |# U
  858. {                                               
    8 j& m! m- ]7 v4 T
  859.         CE_Low();                                /* enable device */
    + n2 u. g$ n9 b$ H- W( L0 L
  860.         Send_Byte(0x60);                /* send Chip Erase command (60h or C7h) */% D+ O+ M9 t* O
  861.         CE_High();                                /* disable device */* U& t2 ?- B& w. a8 f
  862. }& U$ T. u# h* e; _8 s1 S+ |/ O
  863. " E- x. \* L$ e
  864. /************************************************************************/3 c* m# z+ \# Z% ~+ x
  865. /* PROCEDURE: Sector_Erase                                                                                                */2 Q6 S( H: H* I  m( o% d2 N' p4 }' H
  866. /*                                                                                                                                                */  t& t% z2 E; \/ S1 F
  867. /* This procedure Sector Erases the Chip.                                                                */+ j& a) U2 h& d7 a" i& b6 I( H& M
  868. /*                                                                                                                                                *// a4 t& Y/ ]$ p. W: O* Y4 w
  869. /* Input:                                                                                                                                */2 [6 ]( S6 o# k! ^
  870. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    : a  x- `/ y- c3 j! M- S# k! i
  871. /*                                                                                                                                                */
    % p3 @. Q+ z/ o# U% C! P
  872. /* Returns:                                                                                                                                */
    ( T8 f( r, T. o# W" x6 D/ u
  873. /*                Nothing                                                                                                                        */
    . b( R5 O  e* y& X
  874. /************************************************************************/* t! V0 r7 M* w$ d" B
  875. void Sector_Erase(unsigned long Dst)1 k3 i3 ~4 K9 ]& G3 o5 b  n
  876. {
    & W0 J$ S8 g9 D* u# [9 D9 `
  877. $ `9 I. h# u' R1 ]2 e5 n! i8 N

  878. ' H' Z: @; L* o, a' H5 z8 R
  879.         CE_Low();                                        /* enable device */  x; i8 x/ k, h; m
  880.         Send_Byte(0x20);                        /* send Sector Erase command */1 a: J0 m1 U4 }) E
  881.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */8 P# J' O0 \2 F  t0 |$ }7 W! |% j) q
  882.         Send_Byte(((Dst & 0xFFFF) >> 8));
    / ^: y6 L6 N- G4 G4 u
  883.         Send_Byte(Dst & 0xFF);% u$ b3 [; x' n, d& H4 o
  884.         CE_High();                                        /* disable device */
      e% G4 h- ?& N% q
  885. }        ; t6 C2 b7 f4 I  }9 k
  886. # F2 `* }0 m$ S. C
  887. /************************************************************************/( C0 V0 h6 Z: Y, J  R5 T
  888. /* PROCEDURE: Block_Erase_32K                                                                                        */2 f& g! P) U0 X4 c
  889. /*                                                                                                                                                */
    * Y9 ]7 b) ^5 |3 C+ L& `
  890. /* This procedure Block Erases 32 KByte of the Chip.                                        */
    7 R  e/ n; k1 o, E, ?  d
  891. /*                                                                                                                                                */4 P- |; y" A" M& X" B
  892. /* Input:                                                                                                                                */6 t, N' T$ X% _# B4 U0 A
  893. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */
    & @  R! s4 I/ Z5 K, ]' m( ?2 y
  894. /*                                                                                                                                                */4 z6 j+ G4 ?! }0 X) A* H8 o3 `: _
  895. /* Returns:                                                                                                                                */! k. t5 ~1 n# m2 B
  896. /*                Nothing                                                                                                                        */! x3 f8 z# G) P' M
  897. /************************************************************************/
    3 ]6 `! X7 s% Z% T6 F
  898. void Block_Erase_32K(unsigned long Dst)! g# F; p% b# {; l- H. U
  899. {
    " F! @  ?5 ~8 F$ z. o3 n
  900.         CE_Low();                                        /* enable device */
    3 L; e$ V" Q8 x1 D. R$ v* X2 j1 F5 V
  901.         Send_Byte(0x52);                        /* send 32 KByte Block Erase command */$ a+ j3 S' G1 |
  902.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */
    4 I# z6 |. E- a
  903.         Send_Byte(((Dst & 0xFFFF) >> 8));
    # P- Q" j3 ~& e/ E$ w2 m& W
  904.         Send_Byte(Dst & 0xFF);
    % @* o  l, @  {/ [6 J
  905.         CE_High();                                        /* disable device */3 _5 s1 F  n0 u6 t: E2 J
  906. }
    6 C2 i* H; S6 v8 M5 g

  907. " |) s% e) l7 K2 x0 T
  908. /************************************************************************/
    3 P: J* V$ z& t+ x6 }1 p5 X. I$ t- g9 Z
  909. /* PROCEDURE: Block_Erase_64K                                                                                        */
    + D2 U6 _7 ?! |9 {5 B
  910. /*                                                                                                                                                */# |: O8 R, o* x1 D. U) W3 u
  911. /* This procedure Block Erases 64 KByte of the Chip.                                        */
    & |, S8 s- P8 j. j" X* M, Y0 y
  912. /*                                                                                                                                                */
    1 `4 K5 x- V  A& S0 J  k7 U
  913. /* Input:                                                                                                                                */
    4 ~8 X% S9 e% Y/ U' G  P: \
  914. /*                Dst:                Destination Address 000000H - 0FFFFFH                                */1 @8 z+ d( J' q$ c% z+ B4 ^
  915. /*                                                                                                                                                */" b' u8 h2 y+ Y+ J! d
  916. /* Returns:                                                                                                                                */% A. q; p& \4 u# u* ~$ a
  917. /*                Nothing                                                                                                                        */
    + n/ a% x, [$ P! r1 s4 k
  918. /************************************************************************/
    , x; L- Q* i+ s, O+ A. J6 B
  919. void Block_Erase_64K(unsigned long Dst)1 e& S( O6 E: a! x! z9 _
  920. {% L0 b$ z( w* m1 \
  921.         CE_Low();                                        /* enable device */% ]! c3 ?% H- H
  922.         Send_Byte(0xD8);                        /* send 64KByte Block Erase command */
    - U0 }0 C5 }  u4 I/ `, C% t2 L  Z/ M2 U
  923.         Send_Byte(((Dst & 0xFFFFFF) >> 16));         /* send 3 address bytes */  Y5 B" m7 d5 M
  924.         Send_Byte(((Dst & 0xFFFF) >> 8));9 L' E1 J( s3 S+ B7 o: O
  925.         Send_Byte(Dst & 0xFF);
    , ~% V- L* J3 G4 {0 f, J8 F! ^# q
  926.         CE_High();                                        /* disable device */
    5 J5 ]3 O6 f* N. X; |/ P4 M
  927. }
    7 ?9 R, P# v& m) Z9 H; n& e
  928. $ \5 k0 K0 B; {( J! M# q0 p
  929. /************************************************************************/3 A6 Y5 w! e3 E, l% ]2 M
  930. /* PROCEDURE: Wait_Busy                                                                                                        */
    8 W; e3 v- F- s( I- G
  931. /*                                                                                                                                                */
    * k: W. V( S7 b, k
  932. /* This procedure waits until device is no longer busy (can be used by        */
    " j- V" Z) f; z7 F
  933. /* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase).                                */8 p; M8 \9 K4 t, c  G5 B
  934. /*                                                                                                                                                */- B2 P1 D5 q+ K3 q6 r
  935. /* Input:                                                                                                                                */+ _5 Z4 \* W0 L
  936. /*                None                                                                                                                        */
    / ~% K. z5 \- S+ M
  937. /*                                                                                                                                                */
    * P7 k4 ?) \$ }# G2 P
  938. /* Returns:                                                                                                                                */
    ) l3 ]- A& E4 m1 w
  939. /*                Nothing                                                                                                                        */  L! c! a! x  F" m4 I: H
  940. /************************************************************************/5 }: e8 e2 O/ E6 j- s/ R" Z7 x
  941. void Wait_Busy()
    ) e' S$ z1 O/ M5 k
  942. {
    8 z8 b1 r$ }* v% N- L5 o
  943.         while (Read_Status_Register() == 0x03)        /* waste time until not busy */
    * P% T& J; M6 \. @* Y) ]4 V: q
  944.                 Read_Status_Register();
    : L5 ]# Y9 }* O  x
  945. }  d: @  {8 C+ ?
  946. 8 ~3 Y: Q9 C7 b. t) A0 A
  947. /************************************************************************/- L$ W9 x, o/ ]; W6 d5 A) y4 ]8 n9 }
  948. /* PROCEDURE: Wait_Busy_AAI                                                                                                */  d! n9 @- u; K, Y1 s
  949. /*                                                                                                                                                */( w+ e, t; i5 S7 X
  950. /* This procedure waits until device is no longer busy for AAI mode.        */8 ?! H: a0 C3 ?# B9 ]8 L
  951. /*                                                                                                                                                */# }1 c8 C# I1 T2 M+ }# N
  952. /* Input:                                                                                                                                */9 C$ J9 ?; p, A5 e
  953. /*                None                                                                                                                        */
    ' h) F: ~# P7 G
  954. /*                                                                                                                                                */" }& [% r$ J  x9 {  e" L
  955. /* Returns:                                                                                                                                */
    + c+ l+ G8 c+ P5 A% F+ V
  956. /*                Nothing                                                                                                                        */
    4 o5 I! Z. ?- s5 l; H- I
  957. /************************************************************************/
    ; ^/ G7 I/ X& K3 R! I4 t
  958. void Wait_Busy_AAI()- N! o  L& t# i1 |! p3 M% Z3 z+ X
  959. {& s) o4 r- c- c1 I- B) G
  960.         while (Read_Status_Register() == 0x43)        /* waste time until not busy */8 o' {6 m- P9 W
  961.                 Read_Status_Register();* t2 o' k3 |2 a/ b& D
  962. }7 B% A5 z2 u$ n5 D/ }; R) H: {2 a+ j

  963. 3 g, {& O. J. E3 l& z
  964. /************************************************************************/
    ' E+ O* W  b" m* S2 b
  965. /* PROCEDURE: WREN_Check                                                                                                */
    % F+ O0 v7 i. K$ O; }# }2 t
  966. /*                                                                                                                                                */( E( q, b7 E# G1 x5 v
  967. /* This procedure checks to see if WEL bit set before program/erase.        */
    " M5 |( ^4 A! R1 Q
  968. /*                                                                                                                                                */
    $ B3 c0 y+ u& E
  969. /* Input:                                                                                                                                */& A$ _; ?$ P: Z8 W
  970. /*                None                                                                                                                        */
    ; a8 \  C7 b  v7 J, G" [4 H- d/ J, d
  971. /*                                                                                                                                                */
    % F  `, o! B  q( |/ d% ^
  972. /* Returns:                                                                                                                                */
    , f6 y% Q% `4 b. C
  973. /*                Nothing                                                                                                                        */
    & @( `0 K7 P! O* A" K2 Q
  974. /************************************************************************/0 F% ?: v( z6 L6 m' ]+ o
  975. void WREN_Check()
    . N  h% b4 e  z1 ?8 S# X( W/ A1 o
  976. {
    5 X$ ^7 X% P6 d1 ~0 Q& \
  977.         unsigned char byte;& J1 ]0 M; J3 H# t# w" T2 q5 {
  978.         byte = Read_Status_Register();        /* read the status register */
    , s- l) G5 e, J. X5 z
  979.         if (byte != 0x02)                /* verify that WEL bit is set */5 q1 G9 M; C; R3 D* h% X7 p
  980.         {
    / N; Q. K7 h; y% r
  981.                 while(1)4 h7 w) p# X0 `
  982.                         /* add source code or statements for this file */
    . O$ Q, s9 T5 b; H
  983.                         /* to compile                                  */4 s  l. O6 V2 j* l' x( U) x( e4 R
  984.                         /* i.e. option: insert a display to view error on LED? */
    9 e( L9 ^9 ~4 {2 q
  985.                  
    - g% u' H; X, W1 B+ L1 j' y9 Q
  986.         }) m/ f2 M# A1 k1 V( ?
  987. }* W' B0 i) m' S* C% o' N
  988. # b/ _! `8 o! Y) G' U; R' ?$ J
  989. /************************************************************************/! l, b6 P( L, g, m$ s
  990. /* PROCEDURE: WREN_AAI_Check                                                                                        */" i) K8 X) r# |
  991. /*                                                                                                                                                */
    : v( }' L6 o& T6 T" h  @+ P
  992. /* This procedure checks for AAI and WEL bit once in AAI mode.                        */8 a9 n& v; o7 u
  993. /*                                                                                                                                                *// M( y9 g3 j; Q& X
  994. /* Input:                                                                                                                                */
    ' X( H8 s* @8 G
  995. /*                None                                                                                                                        */
    ( b" q) ]$ l! Q, |. v
  996. /*                                                                                                                                                */, n  G/ {6 m- ~) o$ |9 m+ I- ]0 }
  997. /* Returns:                                                                                                                                */6 }3 q9 }2 W, \* j/ u; a
  998. /*                Nothing                                                                                                                        *// `. z, i+ v- C! L+ k* t' J) E
  999. /************************************************************************/
    8 S- ^* D! @( T. H& }$ m% J+ a
  1000. void WREN_AAI_Check()9 H& d6 \  }: ]
  1001. {
    1 Y/ F5 }; N- k/ p; E  M! H! w
  1002.         unsigned char byte;4 j, ~% m+ C* v" r" n
  1003.         byte = Read_Status_Register();        /* read the status register *// y8 w% v3 p1 K# [8 o
  1004.         if (byte != 0x42)                /* verify that AAI and WEL bit is set */
    9 J$ I! F5 W$ j  H. l( B/ K
  1005.         {
    - F" V/ F2 ~4 X, M) c6 t
  1006.                 while(1)               
    ! l" S- q( J* V; ?
  1007.                         /* add source code or statements for this file */
    7 e# l8 ]: r+ A3 v3 o, M
  1008.                         /* to compile                                  */+ O8 {/ c; b9 u3 O! a+ k8 }5 _  |
  1009.                         /* i.e. option: insert a display to view error on LED? */0 X8 Y; a6 ^  J6 O2 Y
  1010. 3 C+ q- ]$ G# `/ X9 g
  1011.         }
    / j/ d- y+ a+ \
  1012. }9 n- v3 P, c2 Y8 g% U5 P/ J% E

  1013. " ], U/ @9 y4 |2 B
  1014. /************************************************************************/
    1 J! r9 N0 P7 Y0 H
  1015. /* PROCEDURE: Verify                                                                                                        */: P' a) |) ^0 B% |1 Y& z' l2 u$ |
  1016. /*                                                                                                                                                */( n! z! `: ?6 c8 I* z  r
  1017. /* This procedure checks to see if the correct byte has be read.                */
    8 {- g$ |- P) }2 c
  1018. /*                                                                                                                                                */
    ) a  l- \9 H/ _+ d
  1019. /* Input:                                                                                                                                */; S1 ]. U7 {- `  A/ H
  1020. /*                byte:                byte read                                                                                        */
    0 A- R" c* B1 b$ ^1 z" i- S3 n
  1021. /*                cor_byte:        correct_byte that should be read                                        */
    . j$ c+ o% o' `& X- r! p6 {
  1022. /*                                                                                                                                                */$ J8 W% m, g8 a, x2 B$ l
  1023. /* Returns:                                                                                                                                */
    # z# j% p3 M# J9 |
  1024. /*                Nothing                                                                                                                        */
    + \6 ~' |" n! `1 e
  1025. /************************************************************************/3 P: j  x( M! k% M
  1026. void Verify(unsigned char byte, unsigned char cor_byte)
    1 R% I8 w; \6 {; _+ {% f' j
  1027. {
    , h- F# r2 A- R. S1 m$ L
  1028.         if (byte != cor_byte)9 j3 a6 R! U, b, X4 }, s- c" s5 {
  1029.         {
    ) x- l* C0 ~1 c0 {' c
  1030.                 while(1)
    6 L  X2 m! \5 v0 `' f+ n1 ~
  1031.                         /* add source code or statement for this file */* G: n; g& C: M
  1032.                         /* to compile                                  */2 i1 ^/ m5 w; H+ a5 U
  1033.                         /* i.e. option: insert a display to view error on LED? */
    $ j3 ~" W' W+ ?. ^5 \* h! Q1 C, a
  1034.                
    1 |3 G2 [3 Y( e6 b1 v
  1035.         }
    ; K9 d" j* f: |- r! ]' @5 L
  1036. }
    0 m$ ^7 S3 Y5 L; _( j0 A0 ~0 f9 e

  1037. 7 x, {" Z: l- M  M/ \
  1038. 2 [4 s+ n. x( g" h' `
  1039. int main()
    ) C$ m( |( T% N1 D! {2 T$ a( L. R
  1040. {# D1 k- H5 i9 p4 D/ C" c3 J
  1041. # ?  I5 A0 X( d4 e4 W* L
  1042. return 0;- o6 H1 ?6 Z9 ~) X. j
  1043. }
复制代码
发表于 2007-12-11 18:30:23 | 显示全部楼层
老大:
# C9 z( m% J" I8 X) w+ j+ V) p   main()
% n8 F4 l/ b0 [2 ^   里面怎么是空的呢?$ _! `) X$ q, ]# X+ u; L5 e' I3 k& I
   发一份给我吧
; b+ e0 @5 w1 k3 }2 W. L( jmail:luyijun2005@hotmail.com% u* {% \: v+ f5 ^+ T% u
咯。。。。
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2008-1-8 17:42:29 | 显示全部楼层
另外请问:EC使用SPI flash的时候,EC firmware是直接在flash上运行吗?还是dump到EC内部的ram运行?直接在flash上运行会不会速度不够快?因为SPI是串行的,还要过转换才能得到指令阿,然后MCU才能执行。
# D9 @& S% [6 m/ B0 @  L9 W
$ R; |" `8 R" G0 G[ 本帖最后由 screw 于 2008-1-8 17:46 编辑 ]
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2008-1-10 17:30:38 | 显示全部楼层
每个FLASHROM的SPI协义部分几乎都在自己的DataSheet(DS)里有。
3 Q; T/ ^; a4 vEC的代码在哪跑,你看DS的说明,每个EC都不同的。  v! y/ Y8 o* t  S& G1 E" P3 R
OEM用多大的FLASH,是由OEM决定的。或者你去各计算机厂商的网站上看看他们BIOS下载的文件有多大不就知道了?$ A" G5 c& y' `+ n/ O: @) r3 o
上面几个问题是你没看任何东西而白问。
: }  Z9 J* H$ d  ^6 |+ Y! ^7 R( o- t. L8 w9 s$ n
至于冷清,那是一定的。中国大陆本来就没多少静下心来做技术的。请问一下,你有静下心来看过spec了么?hoho...
回复

使用道具 举报

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

* d. C9 E, Q0 v2 u关于flash的大小,我当然知道是OEM定义,所以我才问“OEM一般使用多大的flash?”。因为我猜想您应该在BIOS厂家做过,所以想问一下。何况Flash的大小跟BIOS code的大小不一定等价啊...! Z( M8 W! x. N* L; X1 D" i
( X; _' D; X+ X& H2 }7 t
不管怎么说,多谢。
回复

使用道具 举报

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

使用道具 举报

发表于 2009-7-3 12:14:41 | 显示全部楼层
楼上这位前辈与我目前遇到的问题一样
; V/ T- s) i8 c1 T, @' M* V7 G似乎要把SPI能support 到最大,这EC chip应该有好卖点" U) l- s7 Y* W; ^0 ]" b. y; o* X
BIOS功能要不要强大,也就决定了SPI Flach的大小
) z! Z# E+ L5 e/ ^* T我是这么想的~让OEM去决定要挂多大!) _6 I- ?+ k0 j! m
如果我司有BIOS工程师就好了~哈0 K! g8 u( B# _  Y
WPCE775应该算很新的东西,来看它支持到多大?2 I+ x3 B. b- j

: z/ n# ?, y* I' v: q3 U. W另外,我觉得好多人都说会抢BUS,那肯定EC也是经过SPI 去fetch code来执行,但应该不用解到内存,因为8051的内存只做128byte3 A, `" S, P1 i7 s. B' v2 Q" Y& a
其它2K byte是放在SPI flash上(ENE),不会多花时间去存放,然后再decode一次执行代码.5 B- _2 V; ?9 ^) o5 t7 ^  R
* a: }4 }) e* a& |1 \+ A+ f
这份driver收下~希望以后有用到
9 U' Q# d, C- J2 ]1 @$ P) `4 o谢谢bini大大' Y* T" u9 Z0 _1 I9 h4 G9 L1 V& `

6 `# Y  B7 M. n- N$ f/ e很新很新的新手,如有错误请指正 (准备看第二家的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()
8 }- l. R' L2 V; T# ~* j9 w. l% V{8 w7 X/ |+ _# _  [) {- L! R3 o
        unsigned char temp = 0;
; `4 S2 c3 L1 f$ g+ R) Z( W, D        CE_Low();7 w5 s& ?- e% [4 j2 N& H$ E  c" Z
    while (temp == 0x00)        /* waste time until not busy */( d  c+ v5 \2 V6 d  r* |
                temp = SO;7 U% A- D# y! `2 {0 e0 F9 l! O) O' j2 k9 s
        CE_High();& g& ?" q& M( x) o+ n0 E
}
回复

使用道具 举报

发表于 2009-8-17 17:00:56 | 显示全部楼层
void Send_Byte(unsigned char out)
: y( j5 b* C8 Q! t4 X% G$ _{- z4 h- Y9 ]" `' \1 B: K4 s) ?
        
! s% ~. w4 Y! _, L# \        unsigned char i = 0;; T6 f; G' F7 V- r! U) S, y$ n
        for (i = 0; i < 8; i++)1 S  Y3 H) t6 \" v+ H
        {' g, M9 Y5 R- \  |
               
7 i7 M& ^3 d8 X4 M% R+ q; _" _                if ((out & 0x80) == 0x80)        /* check if MSB is high */' n' W* i5 {* L1 @/ `9 _0 l
                        SI = 1;) M7 g5 A6 v* |, ?3 S- {: g- I
                else
8 Z4 D$ Q  ^  r9 k2 ]  A4 x                        SI = 0;                                /* if not, set to low */9 W, A/ W: U. s! h5 t8 C2 m
问              SCK = 1;                                /* toggle clock high */0 t- f5 U$ d$ g6 I
   题            out = (out << 1);                /* shift 1 place for next bit */5 W, V7 Y: I0 n
                SCK = 0;                                /* toggle clock low */6 o8 s* v4 o  I9 r3 f
        }2 s/ X: }0 y; Q- a" u  u. {
}  m- j5 s- I8 r0 t
如果将SCK = 1; out = (out << 1); 调换。会因sck置位时间过短,而出现问题吗?
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-23 20:24 , Processed in 0.079040 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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